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

Dav*_*one 177 regex

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

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

除"apple"或"banana"之外的任何单词均无效.

对于这三种情况,我想分别匹配"apple","banana"和"".请注意,我从不想捕获连字符,但我总是希望匹配它.如果字符串不是123-...456如上所述的形式,那么根本就没有匹配.

如何编写正则表达式来执行此操作?假设我有一种风格,允许前瞻,后视,环视和非捕获组.


这里的关键观察是,当你有"苹果"或"香蕉"时,你还必须有尾随连字符,但你不想匹配它.当您匹配空白字符串时,您不能使用尾随连字符.我认为,封装这个断言的正则表达式将是正确的.

Gum*_*mbo 237

不捕获内容的唯一方法是使用环视断言:

(?<=123-)((apple|banana)(?=-456)|(?=456))
Run Code Online (Sandbox Code Playgroud)

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

|Lookaround  |    Name      |        What it Does                       |
-----------------------------------------------------------------------
|(?=foo)     |   Lookahead  | Asserts that what immediately FOLLOWS the |
|            |              |  current position in the string is foo    |
-------------------------------------------------------------------------
|(?<=foo)    |   Lookbehind | Asserts that what immediately PRECEDES the|
|            |              |  current position in the string is foo    |
-------------------------------------------------------------------------
|(?!foo)     |   Negative   | Asserts that what immediately FOLLOWS the |
|            |   Lookahead  |  current position in the string is NOT foo|
-------------------------------------------------------------------------
|(?<!foo)    |   Negative   | Asserts that what immediately PRECEDES the|
|            |   Lookbehind |  current position in the string is NOT foo|
-------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

  • 不支持JavaScript,*yay*!有一个JS友好的方法会很好,但一点也不差,+ 0.5(四舍五入; D) (7认同)
  • +1 — 在这种情况下,您可以通过使用组 1 而不是组 0 来解决这个问题,但这是一个极好的(而且微妙的!)区别。 (2认同)

op1*_*kun 14

更新:感谢GermánRodríguezHerrera!

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

请记住,结果在第1组中

Debuggex演示


Tho*_*mas 9

尝试:

123-(?:(apple|banana|)-|)456
Run Code Online (Sandbox Code Playgroud)

这将匹配apple,banana或一个空字符串,并在其后面将有一个0或1个连字符.我不需要捕获组.傻我.

  • 这是不正确的,因为它匹配“123-coconut-456”等。 (2认同)
  • 以为你想要它更通用......修复。 (2认同)
  • 这将匹配''123--456'` (2认同)

小智 6

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

123-(apple(?=-)|banana(?=-)|(?!-))-?456
Run Code Online (Sandbox Code Playgroud)

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


slo*_*osd 4

尝试这个:

/\d{3}-(?:(apple|banana)-)?\d{3}/
Run Code Online (Sandbox Code Playgroud)