正则表达式负向后视没有按预期工作
Regex negative look behind isn't working as expected
在 python 中我使用了这个正则表达式
(?<!\d\d\d)(\s?lt\.?\s?blue)
在此字符串上
ltblue
500lt.blue
4009 lt blue
lt. blue
032 lt red
我希望它能捕捉到这个
ltblue
lt. blue
但它却捕获了
ltblue
lt. blue
lt blue
根据我的写法,我认为它不应该在 4009 之后捕获 'lt blue',但出于某种原因,\s?在 'lt' 似乎不起作用之前,有人知道我如何更改正则表达式以获得预期的输出吗?
如果数字总是出现在字符串的开头,并且任何行中数字之前没有任何内容,那么您可以使用:^(?![\d ]+)(lt[ .]*blue)
演示:https://regex101.com/r/sR18Rz/1
你的模式匹配 '4009 lt blue' 的原因是,在 l 之前,\s?
匹配空格零次并且 'l' 前面没有三个数字。
Regex 将尝试通过各种方式匹配您的模式,因此如果 \s
是可选的,它会尝试使用和不使用并保持匹配。在 4009 lt blue
的情况下,如果组中有 no space 则匹配(space 是 before群里,忽悠你的后视)。
由于后视在 python 中必须具有固定宽度,因此您不能将 \s?
添加到负向后视,但您仍然可以在另一个中处理这种情况:
(?<!\d{3})(?<!\d{3}\s)(lt\.?\s?blue)
作为替代方案,您可以使用 Pypi regex module 添加一个可选的 \s?
到后视,并且您可以仅省略匹配的捕获组。
import regex as re
pattern = r"(?<!\d\d\d\s?)lt\.?\s?blue\b"
s = ("ltblue\n"
"500lt.blue\n"
"4009 lt blue\n"
"lt. blue\n"
"032 lt red")
print(re.findall(pattern, s))
看到一个regex demo and a Python demo。
输出
['ltblue', 'lt. blue']
在 python 中我使用了这个正则表达式
(?<!\d\d\d)(\s?lt\.?\s?blue)
在此字符串上
ltblue
500lt.blue
4009 lt blue
lt. blue
032 lt red
我希望它能捕捉到这个
ltblue
lt. blue
但它却捕获了
ltblue
lt. blue
lt blue
根据我的写法,我认为它不应该在 4009 之后捕获 'lt blue',但出于某种原因,\s?在 'lt' 似乎不起作用之前,有人知道我如何更改正则表达式以获得预期的输出吗?
如果数字总是出现在字符串的开头,并且任何行中数字之前没有任何内容,那么您可以使用:^(?![\d ]+)(lt[ .]*blue)
演示:https://regex101.com/r/sR18Rz/1
你的模式匹配 '4009 lt blue' 的原因是,在 l 之前,\s?
匹配空格零次并且 'l' 前面没有三个数字。
Regex 将尝试通过各种方式匹配您的模式,因此如果 \s
是可选的,它会尝试使用和不使用并保持匹配。在 4009 lt blue
的情况下,如果组中有 no space 则匹配(space 是 before群里,忽悠你的后视)。
由于后视在 python 中必须具有固定宽度,因此您不能将 \s?
添加到负向后视,但您仍然可以在另一个中处理这种情况:
(?<!\d{3})(?<!\d{3}\s)(lt\.?\s?blue)
作为替代方案,您可以使用 Pypi regex module 添加一个可选的 \s?
到后视,并且您可以仅省略匹配的捕获组。
import regex as re
pattern = r"(?<!\d\d\d\s?)lt\.?\s?blue\b"
s = ("ltblue\n"
"500lt.blue\n"
"4009 lt blue\n"
"lt. blue\n"
"032 lt red")
print(re.findall(pattern, s))
看到一个regex demo and a Python demo。
输出
['ltblue', 'lt. blue']