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

Python正则表达式:单词集的交替,python,regex,Python,Regex,我们知道\ba\b|\b\b将匹配单词“a”或“the” 我想构建一个正则表达式来匹配如下模式 一个原因 这意味着我要匹配包含3个单词的字符串s: s的第一个单词应该是“a”、“the”或“one” 第二个单词应该是“原因”或“原因” s的第三个单词应该是“for”或“of” 正则表达式\ba\b | \b\bone\b\breason\b | reasons\b | reasons\b\b\b\b\b\bof\b没有帮助 我该怎么做?顺便说一句,我使用python。谢谢。使用括号进行分组:

我们知道
\ba\b|\b\b
将匹配单词“a”或“the
我想构建一个正则表达式来匹配如下模式

一个原因

这意味着我要匹配包含3个单词的字符串
s

  • s
    的第一个单词应该是“a”、“the”或“one
  • 第二个单词应该是“原因”或“原因”
  • s
    的第三个单词应该是“for”或“of
正则表达式
\ba\b | \b\bone\b\breason\b | reasons\b | reasons\b\b\b\b\b\bof\b
没有帮助


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

使用括号进行分组:

'\b(a|the|one) reason(|s) (for|of)\b'
我省略了internal
\b
,因为空格意味着它们:字母后面的空格始终是单词的边界。一般来说,你应该把
\b
放在备选方案之外;它更短,可读性更强


如果有必要,您可以在所有现代regexp引擎中使用“非捕获组”:使用
(?:stuff)
而不是
(stuff)
。但是,如果这与你的用途无关,或者你需要知道哪个词的替代词实际上存在,那么就用简单的paren

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

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

\b(?:a|the|one) reasons? (?:for|of)\b
如果您想在组中输入单词,请使用“捕获组”:

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

正则表达式修饰符
A | B
的意思是“如果A或B匹配,那么整个东西都匹配”。因此,在您的情况下,如果以下5个正则表达式中的任何一个匹配,则结果正则表达式匹配:

  • \ba\b
  • \b\b
  • \bone\b\breason\b
  • 原因\b\b原因\b
  • \bof\b

要限制
|
的应用范围,请使用非捕获分组,即
(?:something | something)
。另外,对于在
原因
末尾有一个可选的
s
,您不需要使用更改;这完全等于
原因?

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


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

据我所知,您需要一些类似以下的正则表达式:

(?:a|the|one)\s+(?:reason|reasons)\s+(?:for|of)
这是如此简单,只要结合使用它们

见:

<强>注<>强>你的要求,它的声音对我来说不是那么严格,如果你想自己修改一些东西,让我们考虑下面的解释

解释

(?:abc|ijk|xyz)

按非捕获组
(?:…)
分组的任何单词
abc
ijk
xyz
表示该单词将不会捕获到regex变量
$1
$2
$3

\s+


这是单词分隔符,我在这里将其设置为任意空格,
+
表示1或多个空格。

的一个有趣功能是命名列表。使用它,您不必在非捕获组中包含由
|
分隔的多个备选方案。您只需要在之前定义列表,并在模式中按其名称引用它。例如:

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))
您只需使用:

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

不,你不需要也不应该t@AnttiHaapala为什么不呢?在这种情况下,它将接受
\bone\b\breason\b
作为一个部分。你说“你需要使用一个捕获组”。你不需要也不应该,你应该使用非捕获组,因为它们可能会有较少的开销(并且在某些情况下捕获组的行为会有所不同)。@AnttiHaapala是的,它们是不同的,因为我建议捕获组限制pip(或)行为!关于
s?
,你是对的,但问题是关于分组备选方案,而不是关于搜索
reason | reasons
@alexis你错了。问题不在于对备选方案进行分组。问题是如何编写一个正则表达式来匹配像a/The/one-reason/reasons for/of这样的模式。
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)
r"\b(a|the)\b"