我有一个字符串,其格式如下
some_string =“,,, xxx ,,, xxx ,,, xxx ,,, xxx ,,, xxx ,,, xxx ,,,” 这是一个名为f
的文本文件的内容我想搜索xxx中的特定术语(假设术语是'硅')
请注意,xxx可以全部不同,并且可以包含除新行之外的任何特殊字符(包括元字符)
match = re.findall(r",{3}(.*?silicon.*?),{3}", f.read())
print match
但这似乎不起作用,因为它返回的格式为: [“xxx ,,, xxx ,,, xxx ,,, xxx ,,,硅”,“xxx ,,, xxx ,,, xxx ,,, xxsiliconxx”]但我只想让它返回[“硅”,“ xxsiliconxx“]
我做错了什么?
答案 0 :(得分:1)
尝试以下正则表达式:
(?<=,{3})(?:(?!,{3}).)*?silicon.*?(?=,{3})
示例:
>>> s = ',,,xxx,,,silicon,,,xxx,,,xxsiliconxx,,,xxx'
>>> re.findall(r'(?<=,{3})(?:(?!,{3}).)*?silicon.*?(?=,{3})', s)
['silicon', 'xxsiliconxx']
我假设xxx
中的内容可以包含逗号,而不是连续三个逗号,或者它会结束字段。如果xxx
部分中的内容不能包含任何逗号,则可以改为使用以下内容:
(?<=,{3})[^,\r\n]*?silicon.*?(?=,{3})
您当前的方法不起作用的原因是即使.*?
尝试匹配尽可能少的字符,匹配仍将尽早开始。例如,正则表达式a*?b
将匹配整个字符串"aaaab"
。正则表达式推进起始位置的唯一时间是正则表达式无法匹配,并且由于,,,
可以匹配.*?
,所以您的匹配将始终从字符串的开头或刚刚开始上一场比赛。
lookbehind和lookahead用于解决JaredC在评论中提出的问题,基本上re.findall()
不会返回重叠匹配,因此您需要前导,,,
不属于{{1}}比赛。