使用NSRegularExpression匹配或(|)的所有可能部分

时间:2012-04-13 16:31:13

标签: ios regex nsregularexpression

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

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

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

3 个答案:

答案 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} )

无论哪种方式,根据表达方式,很多想法都要考虑设计 消费进入正则表达式以避免重叠。