繁体   English   中英

Python正则表达式中的\\ B +与[\\ B] +与[^ \\ b] +

[英]\B+ vs [\B]+ vs [^\b]+ in Python regex

我在回答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匹配的字符集的原因,因此显然可以重复此操作。

\\B+模式不会导致重复错误,当您尝试量化零宽度断言的特殊正则表达式运算符时,该错误不会是常见错误。 任何这些- (*|*\\b+\\B+ 。 -将导致此错误重复零宽度断言是没有意义的,因为它不消耗任何字符和正则表达式指数保持在相同的位置请注意, a{1,2}+f*+ (Python re不支持的所有量词)引起另一个但相似的错误- 多次重复

现在, \\b\\B不能在字符类中使用。 请参阅re Python参考

注意\\b用于表示单词边界,仅在字符类内部表示“退格”。 ...在字符范围内, \\b表示退格字符,以与Python的字符串文字兼容。

还有,仅供参考

\\number
...在字符类的[]内部,所有数字转义符均视为字符。

同样,您不能在字符类中使用\\B\\A\\Z以及像\\1这样的反向引用 它们只是失去了特殊的正则表达式含义,被视为Python认为正确的东西。 实际上,由于Python将无效的转义序列解析为\\ + char, [\\B]仅匹配B char,因为\\正在转义文字符号,并且该符号也是如此 从而,

print(re.findall(r'[\B]+', "BBB \\Bash"))

仅输出['BBB', 'B']

并且r"[^\\b]+"仅匹配不是退格char的所有char:

print(re.findall(r'[^\b]+', "bbb \\bash\baaa"))

输出['bbb \\\\bash', 'aaa']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM