Python正则:如何捕获重复范围匹配的全部子串?问题修复
问题原因
你的正则里,捕获组2写成((?!el)\w+\s+){2,},这里重复限定符{2,}是加在捕获组外面的。正则引擎处理这种结构时,每次重复都会覆盖捕获组的内容,最终捕获组只会保留最后一次匹配的内容,所以你只能拿到sdsdsd 而不是全部目标文本。
解决方法
要捕获所有符合条件的内容,需要把重复逻辑放到捕获组内部:用非捕获组(?:...)包裹单个匹配单元,然后让整个重复的内容被一个捕获组包裹,这样就能把所有连续匹配的内容一次性捕获。
修改后的正则
将原正则中的((?!el)\w+\s+){2,}替换为:
((?:(?!el)\w+\s+){2,})
(?:...)是非捕获组:仅作为重复的单元,不会单独生成捕获组- 外层的
(...)会捕获整个重复2次以上的内容,这样捕获组2就能拿到ssdsdsd sdsdsdsd sdsdsd这类完整目标文本
调整代码逻辑
原代码中lambda m: print(f"{m[2]}")会导致re.sub返回None(因为print()的返回值是None),如果需要保留原文本,lambda应该返回原匹配内容;如果只是提取内容,也可以用re.findall更简洁。
方案1:保留原文本并提取内容
import re input_text = "((PERS)Marcos) ssdsdsd sdsdsdsd sdsdsd le ((VERB)empujé) hasta ((VERB)dejarle) en ese lugar. A ((PERS)Marcos) le ((VERB)dijeron) y luego le ((VERB)ayudo)" # 修改正则,同时让lambda返回原匹配内容以保留文本 processed_text = re.sub( r"\(\(PERS\)((?:\w\s*)+)\)\s*((?:(?!el)\w+\s+){2,})(le)", lambda m: (print(f"捕获到的内容:{repr(m[2])}"), m.group(0))[1], input_text, flags=re.IGNORECASE ) print(repr(processed_text)) # 输出原文本,同时打印捕获内容
方案2:直接提取所有符合条件的内容(更高效)
如果不需要修改原文本,只是提取目标内容,用re.findall更合适:
import re input_text = "((PERS)Marcos) ssdsdsd sdsdsdsd sdsdsd le ((VERB)empujé) hasta ((VERB)dejarle) en ese lugar. A ((PERS)Marcos) le ((VERB)dijeron) y luego le ((VERB)ayudo)" matches = re.findall( r"\(\(PERS\)(?:\w\s*)+\)\s*((?:(?!el)\w+\s+){2,})le", input_text, flags=re.IGNORECASE ) for match in matches: print(repr(match)) # 输出:' ssdsdsd sdsdsdsd sdsdsd '
内容的提问来源于stack exchange,提问作者Matt095
相关产品推荐
相关产品推荐

