正则表达式太宽容了

时间:2016-11-06 20:16:15

标签: python regex python-2.7

我想描述一个正则表达式:

not (a|the) foo

所以(a|the)应该出现它应该匹配以下各项:

not foo
not a foo    
not the foo

在单词之间可能出现任意数量的空格。但这句话:

notfoo

不应该匹配。为此,我做了这个正则表达式:

r = re.compile('not[\s]*[a the]*[\s]+foo')

但是r过于宽松,特别是它会匹配任意数量的[a the]

我尝试使用[a the]?但是它与#34;"不匹配。我应该如何描述匹配零或一个或一个?

的正则表达式

3 个答案:

答案 0 :(得分:4)

这是你在找什么?方括号[a]表示您正在寻找a,space,t,h或e

r = re.compile('not(\s+a|\s+the)?\s+foo')

答案 1 :(得分:2)

您可以将正则表达式与可选组一起使用:

not(?:\s+(?:a|the))?\s+foo
   ^^             ^^

请参阅regex demo

<强>击穿

  • not - not
  • (?:\s+(?:a|the))? - 一个或零(由于?量词)序列:
    • \s+ - 一个或多个空格(如果您使用*,则会匹配零个或多个空格)
    • (?:a|the) - athe个字符序列
  • \s+ - 一个或多个空格
  • foo - foo

答案 2 :(得分:1)

r = re.compile('not[\s]*[a the]*[\s]+foo')

[] vs |

您正在寻找整个字词“a”或“the”。 [ ... ]结构与括号中的任意字母相匹配,因此[a the]*将匹配''ah teeehta,以及你能想到的其他任何有一个或多个这些字母的东西。

而不是[a the]*您正在寻找(a|the)

如果您希望这些字词是可选的,则可以使用?来匹配该组0或1次,如下所示:(a|the)?

所以你会:

r = re.compile('not[\s]*(a|the)?[\s]+foo')

第一个空格匹配的*匹配0个或更多空格,+或第二个匹配1个或多个空格。

空间

您可能不想匹配的一件事是nota foo。您可以通过向(a|the)?组添加空格来避免这种情况:([\s]a|[\s]the)?

r = re.compile('not[\s]*([\s]a|[\s]the)?[\s]+foo')

改进

这可能会满足您的需求,但您可以进行其他一些改进。

您可以使用\b来匹配单词周围的单词分隔符,而不必担心它们之前/之后的空格(请注意,您需要小心使用带有r的原始字符串使用\b时的前缀:

r = re.compile(r'not[\s]*\b(a|the)?[\s]+foo')

请注意,[周围的] ... \s也不需要:

r = re.compile(r'not\s*\b(a|the)?\s+foo')