0

我有一个看起来像这样的正则表达式:

(\bee[0-9]{9}in\b)|(\bee[0-9]{9}[a-zA-Z]{2}\b)

现在如果输入字符串是匹配字符串ee123456789ab的第二部分。|但是,如果输入字符串的ee123456789in第一部分|消耗整个字符串,而第二部分没有更改以匹配字符串?我希望这两个部分|都进行更改以匹配字符串,以便我知道这两个部分都能够匹配字符串。甚至可以使用正则表达式来做到这一点吗?

4

3 回答 3

1

使用正则表达式是不可能的。如果其中任何部分匹配,则视为匹配。你必须用两个不同的表达式来做,看看是否都成功了。

于 2012-04-13T16:53:27.930 回答
1

您可以使用前瞻断言

^(?=(ee[0-9]{9}in$)?)(?=(ee[0-9]{9}[a-zA-Z]{2}$)?)

\1这将在和中捕获匹配项\2;如果两者中的任何一个为空,则正则表达式的相应部分不匹配。

我已将单词边界锚点更改为字符串锚点的开始/结束,因为您正在测试整个字符串,而不仅仅是子字符串。

在 Python 中:

>>> import re
>>> r = re.compile(r"^(?=(ee[0-9]{9}in$)?)(?=(ee[0-9]{9}[a-zA-Z]{2}$)?)")
>>> m = r.match("ee123456789ab")
>>> m.group(1)
>>> m.group(2)
'ee123456789ab'
>>> m = r.match("ee123456789in")
>>> m.group(1)
'ee123456789in'
>>> m.group(2)
'ee123456789in'

解释:

^               # Start of string
(?=             # Look ahead to see if it's possible to match...
 (              # and capture...
  ee[0-9]{9}in  # regex 1
  $             # (end of string)
 )?             # (make the match optional)
)               # End of lookahead
(?=             # Second lookahead, same idea...
 (
  ee[0-9]{9}[a-zA-Z]{2}
  $
 )?
)
于 2012-04-13T17:05:31.960 回答
1

OR 是一个或无论如何,都无法解决这个问题。
正如@Tim 提到的,它可以通过前瞻来完成:

你可以站着不动,不止一次地看同一个文本。

因此,一种方法是不动地查看每个表达式,
每个表达式都是可选的。-

(?= ( ee [0-9]{9} in )? )
(?= ( ee [0-9]{9} [a-zA-Z]{3} )? )

这很糟糕,因为虽然位置会在最后一个
表达式之后前进,但它只会前进 1 个字符间位置。在全局上下文中搜索时,它还
允许重叠。

可以通过消耗一个字符来加快搜索速度 -

(?= ( ee [0-9]{9} in )? )
(?= ( ee [0-9]{9} [a-zA-Z]{3} )? )
.

当某些东西被消耗时,引擎会进行优化,
以块的形式前进(不知道它是如何决定的)。

如果这些表达式中包含其他表达式,则需要将
位置提前到此处,否则将不匹配。这也可以消除
文本的重叠匹配(如果这是一个目标)。

实际上很难避免重叠,除非您确定一个表达式会
比另一个长。如果是这样的话,那么你总是可以做一个有条件的
(如果有的话)来使用更大的文本 -

(?= ( ee [0-9]{9} in )? )
(?= ( ee [0-9]{9} [a-zA-Z]{3} )? )
(?(2) \2 | \1 )

而且,如果你知道一个是另一个的子集,你可以这样做 -

(?= ( ee [0-9]{9} in )? ) ( ee [0-9]{9} [a-zA-Z]{3} )

无论哪种方式,根据表达式的不同,在将
消费设计到正则表达式中时必须考虑很多以避免重叠。

于 2012-04-13T19:45:45.700 回答