0

我有一个具有以下格式的字符串

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,,,silicon", "xxx,,,xxx,,,xxx, ,,xxsiliconxx"] 但我只希望它返回 ["silicon", "xxsiliconxx"]

我究竟做错了什么?

4

1 回答 1

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()不会返回重叠匹配,因此您需要前导和尾随,,,不是匹配的一部分。

于 2013-01-10T01:46:47.047 回答