我有一个字符串列表。其中一些是123-……456的形式。可变部分“…”可以是:

字符串“apple”后面跟着一个连字符,例如123-apple-456 字符串“banana”后面跟着一个连字符,例如123-banana-456 一个空白字符串,例如123-456(注意只有一个连字符)

除“苹果”或“香蕉”外的任何词都无效。

对于这三种情况,我想分别匹配“apple”、“banana”和“”。注意,我从来不想捕获连字符,但我总是想匹配它。如果字符串不是123-…如上文所述456,则根本不匹配。

我如何写一个正则表达式来做到这一点?假设我有一个允许前视、后视、后视和非捕获组的样式。


这里的关键观察是,当你有“apple”或“banana”时,你也必须有后面的连字符,但你不想匹配它。当你匹配空白字符串时,你不能有后面的连字符。我认为封装这个断言的正则表达式是正确的。


当前回答

@Gumbo表达式的一种变体,它使用\K来重置匹配位置,以防止在匹配中包含数字块。可用于PCRE正则表达式风格。

123-\K(?:(?:apple|banana)(?=-456)|456\K)

匹配:

Match 1  apple
Match 2  banana
Match 3

其他回答

我修改了其中一个答案(@op1ekun):

123-(apple(?=-)|banana(?=-)|(?!-))-?456

原因是@op1ekun的答案也匹配“123-apple456”,在apple后面没有连字符。

在javascript中尝试:/ 123 -(苹果(? = -)|香蕉 (?=-)|(?!-))-?456 /

记住,结果在第1组

Debuggex演示


根据Germán Rodríguez Herrera提供的输入

到目前为止,最简单的(适用于python)是“123-(apple|banana)-?456”。

试一试:

123-(?:(apple|banana|)-|)456

它将匹配apple、banana或空白字符串,后面将有一个0或1连字符。我错了,我不需要一个捕捉组。愚蠢的我。

试试这个:

/\d{3}-(?:(apple|banana)-)?\d{3}/