RegExp正则如何匹配除末尾带()分段外的所有蛇形命名分段
原有正则的问题
- 字符集拼写错误:你写的
[a_z]是无效字符集,正确匹配蛇形命名(小写+下划线)的字符集应为[a-z_] - 贪婪匹配逻辑问题:前面的
(\.([a-z]|_)*)*是贪婪匹配模式,会优先尽可能多吞掉符合规则的字符,导致末尾带()的last_name段也被前面的分组捕获,后面的可选匹配分支完全无法生效。
解决方案
方案1:直接匹配单个分段(支持可变长度回顾的正则引擎可用,如Python re、Java 9+、.NET)
用以下正则可直接匹配到所有目标分段,无需额外处理:
(?<=^T\.|\.)[a-z_]+(?=(?:\.[a-z_]+)*$|(?:\.[a-z_]+)*\.[a-z_]+\(\)$)
测试效果:
- 对
T.name.other_name.another_name,匹配结果为name、other_name、another_name - 对
T.name.again_name.ect_name.last_name(),匹配结果为name、again_name、ect_name
方案2:先捕获整体再拆分(兼容性更高)
如果你的正则引擎不支持可变长度回顾,用以下正则先捕获所有目标内容的整体,再按.拆分即可:
^T\.?([a-z_]+(?:\.[a-z_]+)*?)(?:\.[a-z_]+\(\))?$
提取第1个分组的内容后按.拆分,就能得到目标分段列表。
示例效果:
- 匹配
T.name.other_name.another_name时,第1分组值为name.other_name.another_name,拆分后得到目标列表 - 匹配
T.name.again_name.ect_name.last_name()时,第1分组值为name.again_name.ect_name,拆分后得到目标列表
方案3:两步处理(逻辑最简单,不易出错)
如果不想写复杂正则,直接分两步处理即可:
- 先替换掉字符串末尾匹配
\.[a-z_]+\(\)$的内容 - 去掉开头的
T.前缀后按.拆分字符串,得到的就是目标分段
内容的提问来源于stack exchange,提问作者Valentin Vignal
相关产品推荐
相关产品推荐

