正则表达式捕获组未获取完整匹配内容的问题咨询
问题原因
当捕获组被量词(比如你用到的*)修饰时,捕获组只会保留最后一次匹配到的内容,不会累积所有匹配结果。
你的正则'(/[a-zA-Z]+)*/([a-zA-Z]+)\.?$'中,(/[a-zA-Z]+)*会依次匹配路径里的/foo、/bar两段,每次匹配都会覆盖第一个捕获组的存储值,最终第一个捕获组就只剩下最后一次匹配到的/bar,不会保留之前的/foo。
修复方案
如果要捕获前面所有的父路径段,需要把重复匹配的逻辑放在非捕获组里,再在外层套一个捕获组来保存所有匹配内容:
修正后的正则为:^((?:/[a-zA-Z]+)*)/([a-zA-Z]+)(?:\.[a-zA-Z]+)?$
说明:
(?:/[a-zA-Z]+)是不占用捕获组序号的非捕获组,用来匹配单级路径段- 外层的
()把所有重复的父路径段都包裹为第一个捕获组,会保留完整的父路径内容- 末尾的
(?:\.[a-zA-Z]+)?可以更严谨地匹配可选的文件后缀,避免路径名本身带点的情况被误截断,符合你无文件后缀的匹配要求
运行验证
测试代码如下:
import re # 修正后的正则 regex = re.compile(r'^((?:/[a-zA-Z]+)*)/([a-zA-Z]+)(?:\.[a-zA-Z]+)?$') # 测试无后缀的多级路径 match = regex.match('/foo/bar/baz') print(match.group(1)) # 输出 /foo/bar print(match.group(2)) # 输出 baz # 测试带文件后缀的路径 match2 = regex.match('/user/profile/info.html') print(match2.group(1)) # 输出 /user/profile print(match2.group(2)) # 输出 info
内容的提问来源于stack exchange,提问作者Anthony Bias
相关产品推荐
相关产品推荐

