我有一个字符串列表。其中一些是123-...456
的形式。可变部分“...”可以是:
- 字符串“apple”后跟连字符,例如
123-apple-456
- 字符串“banana”后跟连字符,例如
123-banana-456
- 空字符串,例如
123-456
(注意只有一个连字符)
除“apple”或“banana”以外的任何单词都是无效的。
对于这三种情况,我想分别匹配“apple”、“banana”和“”。请注意,我从来不想 * 捕获 * 连字符,但我总是想 * 匹配 * 它。如果字符串不是如上所述的123-...456
形式,则根本没有匹配。
如何编写正则表达式来实现这一点?假设我有一个风格,允许lookahead,lookbehind,lookaround和非捕获组。
这里的关键观察是,当你有“apple”或“banana”时,你 * 必须 * 也有尾随的连字符,但你不想匹配它。当你匹配空字符串时,你 * 不能 * 有结尾的连字符。我认为,封装这个Assert的正则表达式将是正确的。
8条答案
按热度按时间cidc1ykv1#
不捕获某些内容的唯一方法是使用look-around assertions:
因为即使使用non-capturing groups
(?:…)
,整个正则表达式也会捕获它们匹配的内容。但是,如果前面是123-
,后面是-456
,则该正则表达式仅匹配apple
或banana
,或者如果前面是123-
,后面是456
,则该正则表达式匹配空字符串。| 四处看看|姓名、名称|它的作用|
| --------------|--------------|--------------|
| (?=foo)|前瞻|Assert紧跟在字符串中当前位置后面的是foo|
| (?<=foo)|向后看|Assert紧接在字符串中当前位置之前的是foo|
| (?!foo)|负前瞻|Assert紧跟在字符串中当前位置后面的内容是NOT foo|
| (?<!foo)|负后看|Assert紧接在字符串中当前位置之前的内容为NOT foo|
ztyzrc3y2#
在JavaScript中尝试:
/123-(apple(?=-)|banana(?=-)|(?!-))-?456/
记住结果在第1组
Debuggex Demo
基于Germán Rodríguez Herrera提供的输入
fxnxkyjh3#
尝试:
这将匹配
apple
、banana
或一个空字符串,后面将有一个0或1连字符。我错了,我不需要一个捕获组。我真傻n53p2ov04#
我修改了其中一个答案(@op1ekun):
原因是来自@op1ekun的答案也匹配
"123-apple456"
,而没有苹果后面的连字符。dy2hfwbg5#
试试这个:
cedebl8k6#
@Gumbo的表达式的变体,它使用
\K
来重置匹配位置,以防止在匹配中包含数字块。可用于PCRE regex风味。比赛:
qacovj5a7#
回声'16'|沙格什|grep -oP '\d'
kokeuurv8#
到目前为止,最简单的(适用于python)是
'123-(apple|banana)-?456'
。