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

我有一个string列表。 其中一些是123-...456的forms。 可变部分“…”可以是:

  • string“苹果”,后面跟一个连字符,例如123-apple-456
  • string“香蕉”后跟一个连字符,例如123-banana-456
  • 一个空白string,例如123-456 (注意只有一个连字符)

“apple”或“banana”以外的任何词都是无效的。

对于这三种情况,我想分别匹配“苹果”,“香蕉”和“”。 请注意,我不想捕捉连字符,但我总是想要匹配它。 如果string不是如上所述的forms123-...456 ,则根本不匹配。

我如何写一个正则expression式来做到这一点? 假设我有一个风格,允许向前看,向后看,周围和非捕获组。


这里关键的观察是,当你有“苹果”或“香蕉”,你也必须有尾随连字符,但你不想匹配它。 而当你匹配空白string,你不能有尾随连字符。 封装这个断言的正则expression式是正确的,我想。

不捕获某些东西的唯一方法是使用环视声明 :

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

因为即使使用非捕获组(?:…) ,整个正则expression式也会捕获它们的匹配内容。 但是这个正则expression式只匹配apple或者banana如果它的前面是123- ,后面是-456 ,或者匹配空白string,前面是123- ,后面是456

尝试:

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

这将匹配applebanana ,或一个空白的string,并跟随它将有一个0或1连字符。 我错了没有需要一个捕获组。 傻我。

更新:感谢GermánRodríguezHerrera!

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

请记住,结果是在第1组

正则表达式可视化

Debuggex演示

尝试这个:

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

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

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

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

到目前为止,最简单的(Python的作品)是'123-(apple|banana)-?456'