【问题标题】:Combine words from list to single regex with word boundary将列表中的单词组合到具有单词边界的单个正则表达式
【发布时间】:2019-07-20 13:10:23
【问题描述】:

我有一个列表l = [AA, CC, DD, EE]

我有很多来自文件的字符串,我想在其中找到包含列表中任何确切单词的字符串。我不想得到在特定字符串中匹配的单词。阅读其他 SO 问题,我得到的建议主要通过以下两种方式将列表组合成一个正则表达式

1. \bAA\b|\bCC\b|\bDD\b|\bEE\b     ==> r"\b%s\b" % r"\b|\b".join(l)
2. \b(?:AA|CC|DD|EE)\b             ==> r"\b(?:%s)\b" % "|".join(l)

上面右边提到的连接只是一个例子,不是问题的一部分。

运行代码,它们都给出了相同的正确答案,并且 timit 给出了相似的时间。 如果我不关心列表中匹配的单词,是否需要像选项 2 中那样进行分组?为什么选项#2 末尾的单词边界?这是否意味着它适用于括号内的所有单词,即相当于(?:\bAA\b|\bCC\b|\bDD\b|\bEE\b)?谁能指出一个提到这个括号属性的链接? 这两个选项中的任何一个更正确/pythonic?

【问题讨论】:

    标签: regex python-3.x regex-group


    【解决方案1】:

    这两个版本在逻辑上是相同的,应该产生相同的结果,并且也应该具有相似的性能。您实际应该使用的版本是第二个:

    \b(?:AA|CC|DD|EE)\b
    

    原因是它更简洁,并且避免了在交替中为每个术语不必要地重复单词边界。这个正则表达式表示匹配交替中的任何一个术语,两端都有单词边界。关于“组”,括号内的?: 实际上关闭了捕获组,因此至少从性能的角度来看,它实际上并不存在。需要括号以避免重复每个术语的单词边界,这是第一个版本所做的。

    【讨论】:

    • 那么第二个就相当于(?:\bAA\b|\bCC\b|\bDD\b|\bEE\b),分组只是为了避免重复边界?
    • 如果这是整个模式,那么您评论中的正则表达式甚至不需要括号。是的,分组是为了避免重复单词边界。
    • 是的,这就是他的全部模式。所以你是说应该使用选项一吗?这是否意味着括号之前(或之后)的任何内容都应用于所有元素,例如xyz(AA|CC|DD|EE) 等价于(xyzAA|xyzCC|xyzDD|xyzEE)?我无法在文档docs.python.org/3/howto/regex.html#grouping 中找到这样的属性
    • 我不一定希望 Python 文档能够全面介绍正则表达式语法。
    • 我实际上不知道有哪个地方提到了这一点,尽管官方的正则表达式语言规范可能会这样做。一路走来,我学到了大部分的正则表达式知识。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多