我有一个正则表达式,看起来像这样:
(\bee[0-9]{9}in\b)|(\bee[0-9]{9}[a-zA-Z]{2}\b)
现在,如果输入字符串是ee123456789ab
,则|
的第二部分与字符串匹配。但是如果输入字符串是ee123456789in
|
的第一部分消耗整个字符串而第二部分没有得到更改以匹配字符串?我希望|
的两个部分都进行更改以匹配字符串,以便我知道两个部分都能够匹配字符串。甚至可以使用正则表达式来做到这一点吗?
答案 0 :(得分:1)
正则表达式无法实现。如果它的任何部分匹配,则认为是匹配。你必须用两个不同的表达式来做,看看两者是否都成功了。
答案 1 :(得分:1)
您可以使用lookahead assertions:
^(?=(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}
$
)?
)
答案 2 :(得分: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} )
无论哪种方式,根据表达方式,很多想法都要考虑设计 消费进入正则表达式以避免重叠。