在回答一个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
为什么会有这种差异?我不需要更好的解决方案来解决羊/狼放置问题——我只是想理解为什么这三种一个或多个非单词边界模式的变体会产生不同的结果。
我知道\b
像锚一样,它不代表一个字符,而且这个模式考虑不周(与使用`\w'相比),但是为什么会有这种差异呢?
[^\b]+
应该匹配一个或者没有 'b',即与[^b]+
相同,但实际情况并非如此,因为re.search(r"[^\b]+", "bbb")
和re.search(r"[^b]+", "bbb")
产生不同的结果。 - cdlane\b
(方括号内)应该是实际的退格符号。 - Sebastian Proske\B+
解释与\b+
一致,很有道理。两个中有两个正确,加1分! - cdlane