首页 文章

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

提问于
浏览
137

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

  • 字符串"apple"后跟一个连字符,例如 123-apple-456

  • 字符串"banana"后跟一个连字符,例如 123-banana-456

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

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

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

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


这里的关键观察是,当你有"apple"或"banana"时,你还必须有尾随连字符,但是你没有't want to match it. And when you'匹配空白字符串,你不能有尾随连字符 . 我认为,封装这个断言的正则表达式将是正确的 .

6 回答

  • 8

    唯一不捕获东西的方法是使用look-around assertions

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

    因为即使使用non-capturing groups (?:…),整个正则表达式也会捕获其匹配的内容 . 但是这个正则表达式只匹配 applebanana ,如果它前面是 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|
    -------------------------------------------------------------------------
    
  • 12

    更新:感谢GermánRodríguezHerrera!

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

    Remember that the result is in group 1

    Debuggex Demo

  • -2

    尝试:

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

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

  • 3

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

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

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

  • 2

    试试这个:

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

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

相关问题