Python正则表达式:单词集的替换

时间:2015-08-29 08:56:34

标签: python regex

我们知道\ba\b|\bthe\b会匹配任何字词" a "或" "
我想构建一个正则表达式来匹配像

这样的模式
  

的原因/原因之一

这意味着我想匹配一个字符串s包含3个字:

  • s的第一个字应该是" a "," "或" 一个"
  • 第二个词应该是" 原因"或" 原因"
  • s的第三个字应为" "或" "

正则表达式\ba\b|\bthe\b|\bone\b \breason\b|reasons\b \bfor\b|\bof\b没有帮助。

我该怎么做?顺便说一句,我使用python。感谢。

6 个答案:

答案 0 :(得分:3)

您需要使用捕获组来拒绝混合OR(|

(\ba\b|\bthe\b|\bone\b) (\breason\b|reasons\b) (\bfor\b|\bof\b)

然后,作为一种更优雅的方式,您可以将单词边界放在组周围。另请注意,当您在正则表达式中使用空格时,不需要使用单词边界。而reasonsreason您可以使用s制作最后?个可选项。请注意,如果您不希望将单词作为单独的组进行匹配,则可以通过:?将您的论坛设置为无捕获组。

\b(?:a|the|one) reasons? (?:for|of)\b

如果您想要组中的单词,请使用捕获组:

\b(a|the|one) (reasons?) (for|of)\b

答案 1 :(得分:3)

正则表达式修饰符A|B表示“如果A或B匹配,则整个事物匹配”。因此,在您的情况下,生成的正则表达式匹配if / where 以下5个正则表达式中的任何匹配:

  • \ba\b
  • \bthe\b
  • \bone\b \breason\b
  • reasons\b \bfor\b
  • \bof\b

要限制|适用的范围,请使用非捕获分组,即(?:something|something else)。另外,如果s末尾有一个可选reason,则无需使用更改;这完全等于reasons?

因此我们得到正则表达式\b(?:a|the|one) reasons? (?:for|of)\b

请注意,您不需要在正则表达式中使用单词边界运算符\b,仅在开头和结尾使用 (否则它将匹配everyone reasons forever之类的内容)。

答案 2 :(得分:3)

regex module的一个有趣特性是命名列表。有了它,您不必在非捕获组中包含由|分隔的多个替代项。您只需要在之前定义列表,并在模式中按名称引用它。例如:

import regex

words = [ ['a', 'the', 'one'], ['reason', 'reasons'], ['for', 'of'] ]

pattern = r'\m \L<word1> \s+ \L<word2> \s+ \L<word3> \M'
p = regex.compile(pattern, regex.X, word1=words[0], word2=words[1], word3=words[2])

s = 'the reasons for'

print(p.search(s))

即使此功能不是必需的,它也会提高可读性。

如果您之前使用|加入项目,则可以使用re模块实现类似的功能:

import re

words = [ ['a', 'the', 'one'], ['reason', 'reasons'], ['for', 'of'] ]

words = ['|'.join(x) for x in words]

pattern = r'\b ({}) \s+ ({}) \s+ ({}) \b'.format(*words)

p = re.compile(pattern, re.X)

答案 3 :(得分:1)

使用括号进行分组:

'\b(a|the|one) reason(|s) (for|of)\b'

我离开了句子内部\b,因为空格暗示了它们:字母后面的空格始终是单词边界。一般来说,你应该将\b置于替代方案之外;它更短,更易读。

如果重要,您可以在所有现代正则表达式引擎中使用“非捕获组”:使用(?:stuff)代替(stuff)。但是如果它对你的用途无关紧要,或者如果你需要知道实际存在哪个替代词,那么请使用简单的parens。

答案 4 :(得分:1)

据我所知,你想要一些像这样的正则表达式:

(?:a|the|one)\s+(?:reason|reasons)\s+(?:for|of)

这很简单,只需使用groups组合它们。

请参阅:DEMO

注意您的上述要求,对我来说声音不是那么严格,如果您想自己修改某些内容,请考虑以下说明

<强>解释

(?:abc|ijk|xyz)

按非捕获组abc分组的任何单词ijkxyz(?:...)表示此单词不会捕获到正则表达式变量$1,{ {1}},$2$3

...

这是单词分隔符,在这里我将其设置为任何空格,\s+代表1或更多。

答案 5 :(得分:1)

您可以使用:

r"\b(a|the)\b"