如何匹配,但不捕获,正则表达式的一部分?

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

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

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

对于这三种情况,我想分别匹配“apple”、“banana”和“”。注意,我从来不想要捕获连字符,但我总是想要匹配它。如果字符串不是上面描述的123-...456形式,则根本没有匹配。

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


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

246751 次浏览

试试这个:

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

试一试:

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

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

唯一不捕获的方法是使用并且断言:

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

因为即使使用非捕获组(?:…),整个正则表达式也会捕获它们匹配的内容。但是这个正则表达式只匹配applebanana,如果它前面有123-,后面有-456,或者它匹配空字符串,如果它前面有123-,后面有456

看看 的名字 它的作用
(? = foo) 超前 断言字符串中紧跟着当前位置的是foo
(& lt; = foo) 向后插入 断言字符串中紧挨着当前位置的是foo
foo (? !) 消极的超前 断言字符串中紧跟着当前位置的不是foo
(& lt; ! foo) 负向后插入 断言在字符串中当前位置之前的内容不是foo

在javascript中尝试:/123-(apple(?=-)|banana(?=-)|(?!-))-?456/

记住,结果在第1组

Debuggex Demo


基于Germán Rodríguez埃雷拉提供的输入

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

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

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

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

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

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

匹配:

Match 1  apple
Match 2  banana
Match 3