我有一个字符串列表。其中一些形式为123-...456
。可变部分“......”可以是:
123-apple-456
123-banana-456
123-456
(注意只有一个连字符)“apple”或“banana”以外的任何单词均无效。
对于这三种情况,我想分别匹配“apple”,“banana”和“”。请注意,我从不希望捕获连字符,但我总是希望匹配它。如果字符串不是如上所述的123-...456
形式,那么根本就没有匹配。
如何编写正则表达式来执行此操作?假设我有一种风格,允许前瞻,后视,环视和非捕获组。
这里的关键观察是,当你有“苹果”或“香蕉”时,还必须具有尾随连字符,但你不想匹配它。当您匹配空白字符串时,不得具有尾随连字符。我认为封装这个断言的正则表达式是正确的。
答案 0 :(得分:190)
不捕获内容的唯一方法是使用look-around assertions:
(?<=123-)((apple|banana)(?=-456)|(?=456))
因为即使使用non-capturing groups (?:…)
,整个正则表达式也会捕获匹配的内容。但是这个正则表达式只匹配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|
-------------------------------------------------------------------------
答案 1 :(得分:12)
更新:感谢GermánRodríguezHerrera!
在javascript中尝试:/123-(apple(?=-)|banana(?=-)|(?!-))-?456/
请记住,结果在第1组
答案 2 :(得分:8)
尝试:
123-(?:(apple|banana|)-|)456
这将匹配apple
,banana
或空字符串,然后会有0或1个连字符。我不需要捕获组。傻我。
答案 3 :(得分:4)
我修改了其中一个答案(@ op1ekun):
123-(apple(?=-)|banana(?=-)|(?!-))-?456
原因是来自@ op1ekun的答案也匹配"123-apple456"
,而不是苹果后的连字符。
答案 4 :(得分:2)
试试这个:
/\d{3}-(?:(apple|banana)-)?\d{3}/
答案 5 :(得分:0)
@Gumbo表达式的一种变体,它使用\K
来重置匹配位置,以防止在匹配中包含数字块。可用于PCRE正则表达式。
123-\K(?:(?:apple|banana)(?=-456)|456\K)
比赛:
Match 1 apple
Match 2 banana
Match 3
答案 6 :(得分:-2)
到目前为止,最简单的(适用于python)是'123-(apple|banana)-?456'
。