我遇到了一个在回答SO问题时我不理解的问题。我已经创建了一个简化示例来说明问题:
情景:
我正在测试两个令牌(不是随机的英语单词!)在一个字符串中至少有一段距离。在这个例子中,我们有一个动物清单,我们想确保绵羊和狼之间至少有三只其他动物(或者那里有麻烦)。以下代码有效:
import re
safe_distance = re.compile(r"sheep (\b[^\b]+\b ){3,}wolf")
animal_arrangements = [
"dog sheep hen wolf fox cat ox", # one between
"dog sheep hen fox wolf cat ox", # two between
"dog sheep hen fox cat wolf ox", # three between
"dog sheep hen fox cat ox wolf" # four between
]
for i, animal_arrangement in enumerate(animal_arrangements):
if safe_distance.search(animal_arrangement):
print(i + 1, "All is peaceful.")
else:
print(i + 1, "Sheep and wolf too close!")
问题:
在上述模式中,使用:
[^\b]+ # works fine
\B+ # causes a regex compilation error "nothing to repeat"
[\B]+ # runs but produces wrong answers
\w+ # yes, this does work, probably best, but not related to my question
为何与众不同?我不需要更好地解决绵羊/狼的放置问题 - 我只是试图理解为什么这三个一个或多个不是一个词边界的变体< / em>模式产生不同的结果。
我知道\b
,就像一个锚点,并不代表一个角色,而且模板被认真考虑(与使用`\ w&#39;相比),但为什么差异?
答案 0 :(得分:3)
\B+
会导致错误,因为重复边界没有意义 - 一个边界与两个边界相同。你错误地做了这个,所以这个错误是有道理的。[\B]+
是完全不同的东西。 (大多数)转义序列在字符类中不起作用,这就是为什么这是一个与字符\
或B
匹配的字符集,因此显然可以重复此操作。答案 1 :(得分:3)
当您尝试量化一个零宽度断言的特殊正则表达式运算符时,\B+
模式不会导致重复错误,这是一个常见错误。其中任何一项 - (*
,|*
,\b+
,\B+
都会导致此错误。重复零宽度断言是没有意义的,因为它不消耗任何字符并且正则表达式索引保持在相同位置。请注意,a{1,2}+
和f*+
(Python re
不支持的占有量词)导致另一个但类似的错误 - 多次重复。
现在,\b
和\B
不能在字符类中使用。见re
Python reference:
请注意,
\b
用于表示字边界,并且仅在字符类中表示“退格”。 ... 在字符范围内,\b
表示退格符,以便与Python的字符串文字兼容。
另外,仅供参考,
\number
...在字符类的[
和]
内,所有数字转义都被视为字符。
同样,您无法在字符类<{1}}内使用\B
,\A
,\Z
和反向引用 < / em>的。他们只是失去了他们特殊的正则表达式意义,并被视为Python认为正确的。实际上,由于Python将无效转义序列解析为\1
+ char,因此 \
仅匹配[\B]
个字符,因为B
正在转义文字符号且符号为这样匹配。因此,
\
print(re.findall(r'[\B]+', "BBB \\Bash"))
只匹配所有不是退格字符的字符:
r"[^\b]+"