重新 - 负面前瞻是否受先前空间数量的影响?
Re - Is negative lookahead influenced by the amount of previous spaces?
给定以下正则表达式:
import re
pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s+)(?!you shall not match\!)')
和字符串:
a = '1, 2, 3, you shall not match!'
b = '4, 5, 6, you shall not match!'
c = '7, 8, 9, young neil asdfghj'
我们看到:
>>> pattr.search(a)
<_sre.SRE_Match object; span=(0, 13), match='1, 2, 3, '> #With multiple spaces it does match
>>> pattr.search(b) #With a sinlge space it doesn't found anything; returns None
>>> pattr.search(c)
<_sre.SRE_Match object; span=(0, 19), match='7, 8, 9, '>
>>>
我需要修改 pattr
,使其返回 None
pattr.search(a)
和 pattr.search(b)
和 return 与上面 pattr.search(c)
.
相同的输出
如有任何帮助,我们将不胜感激。
a
匹配而 b
不匹配的原因是因为对空白字符的最后一次贪婪匹配,即 )
之前的 \s+
和负先行断言, 匹配最长 有效 匹配。
对于a
,这意味着它匹配的空白字符少于我们凭直觉期望匹配的空白字符。这意味着 1, 2, 3,
和 5 个空白字符,而不是将 1, 2, 3,
与 you shall not match!
分开的全部 6 个。如果它匹配所有 6 个,那么它就不会是一个 有效 匹配,因为你要求 1, 2, 3,
后跟一系列空白字符而不是 you shall not match!
.所以,匹配是可能的,这就是你得到的。
>>> pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s+)(?!you shall not match!)')
>>> pattr.match(a)
<_sre.SRE_Match object; span=(0, 13), match='1, 2, 3, '> # 5 whitespaces matched
>>>
>>> a
'1, 2, 3, you shall not match!' # ... but a has 6
对于b
,事情就简单多了。您要求一个或多个未跟在 you shall not match!
之后的空白字符,如果 1, 2, 3,
和 you shall not match!
之间只有 1 个空白字符,则无法满足这一要求。所以,你找不到匹配项。
您的正则表达式的一个可能更新是添加单词边界(根据您的需要,您可能希望 a. 将 \s*
替换为 \s+
或 b. 包含 \b
括号内,即组):
>>> pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s*)\b(?!you shall not match!)')
>>> pattr.match(a)
>>> pattr.match(b)
>>> pattr.match(c)
<_sre.SRE_Match object; span=(0, 9), match='7, 8, 9, '>
>>>
>>> # a and b do not match and c matches what it did with you regular expression
>>>
>>> pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s+)(?!you shall not match!)')
>>> pattr.match(c)
<_sre.SRE_Match object; span=(0, 9), match='7, 8, 9, '>
另一个可能的更新是模拟“原子匹配”或“占有匹配”:
>>> pattr = re.compile(r'(?=(\d+\,\s+\d+\,\s+\d+\,\s+))(?!you shall not match!)')
>>> pattr.match(a)
>>> pattr.match(b)
>>> pattr.match(c)
<_sre.SRE_Match object; span=(0, 9), match='7, 8, 9, '>
>>> # a and b do not match and c matches what it did with you regular expression
您可能还想查看支持原子分组和所有格量词的 regex module。
给定以下正则表达式:
import re
pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s+)(?!you shall not match\!)')
和字符串:
a = '1, 2, 3, you shall not match!'
b = '4, 5, 6, you shall not match!'
c = '7, 8, 9, young neil asdfghj'
我们看到:
>>> pattr.search(a)
<_sre.SRE_Match object; span=(0, 13), match='1, 2, 3, '> #With multiple spaces it does match
>>> pattr.search(b) #With a sinlge space it doesn't found anything; returns None
>>> pattr.search(c)
<_sre.SRE_Match object; span=(0, 19), match='7, 8, 9, '>
>>>
我需要修改 pattr
,使其返回 None
pattr.search(a)
和 pattr.search(b)
和 return 与上面 pattr.search(c)
.
如有任何帮助,我们将不胜感激。
a
匹配而 b
不匹配的原因是因为对空白字符的最后一次贪婪匹配,即 )
之前的 \s+
和负先行断言, 匹配最长 有效 匹配。
对于a
,这意味着它匹配的空白字符少于我们凭直觉期望匹配的空白字符。这意味着 1, 2, 3,
和 5 个空白字符,而不是将 1, 2, 3,
与 you shall not match!
分开的全部 6 个。如果它匹配所有 6 个,那么它就不会是一个 有效 匹配,因为你要求 1, 2, 3,
后跟一系列空白字符而不是 you shall not match!
.所以,匹配是可能的,这就是你得到的。
>>> pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s+)(?!you shall not match!)')
>>> pattr.match(a)
<_sre.SRE_Match object; span=(0, 13), match='1, 2, 3, '> # 5 whitespaces matched
>>>
>>> a
'1, 2, 3, you shall not match!' # ... but a has 6
对于b
,事情就简单多了。您要求一个或多个未跟在 you shall not match!
之后的空白字符,如果 1, 2, 3,
和 you shall not match!
之间只有 1 个空白字符,则无法满足这一要求。所以,你找不到匹配项。
您的正则表达式的一个可能更新是添加单词边界(根据您的需要,您可能希望 a. 将 \s*
替换为 \s+
或 b. 包含 \b
括号内,即组):
>>> pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s*)\b(?!you shall not match!)')
>>> pattr.match(a)
>>> pattr.match(b)
>>> pattr.match(c)
<_sre.SRE_Match object; span=(0, 9), match='7, 8, 9, '>
>>>
>>> # a and b do not match and c matches what it did with you regular expression
>>>
>>> pattr = re.compile(r'(\d+\,\s+\d+\,\s+\d+\,\s+)(?!you shall not match!)')
>>> pattr.match(c)
<_sre.SRE_Match object; span=(0, 9), match='7, 8, 9, '>
另一个可能的更新是模拟“原子匹配”或“占有匹配”:
>>> pattr = re.compile(r'(?=(\d+\,\s+\d+\,\s+\d+\,\s+))(?!you shall not match!)')
>>> pattr.match(a)
>>> pattr.match(b)
>>> pattr.match(c)
<_sre.SRE_Match object; span=(0, 9), match='7, 8, 9, '>
>>> # a and b do not match and c matches what it did with you regular expression
您可能还想查看支持原子分组和所有格量词的 regex module。