正则表达式匹配除字符串外的所有字符
我需要找到匹配模式的所有字符串,但两个给定字符串除外。正则表达式匹配除字符串外的所有字符
例如,找到除aa
和bb
之外的所有字母组。从这个字符串开始:
-a-bc-aa-def-bb-ghij-
应返回:
('a', 'bc', 'def', 'ghij')
我试着用this regular表达,抓住4串。我认为我正在接近,但(1)它在Python中不起作用,(2)我无法弄清楚如何从搜索中排除几个字符串。 (是的,我可以稍后删除它们,但是我真正的正则表达式只能一次完成所有操作,我希望在其中包含最后一步。)
我说它在Python中不起作用,因为我试过这个,期待完全相同的结果,而是我得到的只有第一组:
>>> import re
>>> re.search('-(\w.*?)(?=-)', '-a-bc-def-ghij-').groups()
('a',)
我负尝试一下未来,但我无法找到这种情况下,一个可行的解决方案。
您可以使用负的样子aheads的。
例如,
>>> re.findall(r'-(?!aa|bb)([^-]+)', string)
['a', 'bc', 'def', 'ghij']
-
相配-
(?!aa|bb)
负先行,检查是否-
后面没有aa
或bb
- 个
([^-]+)
相配ONY或比其它多个字符-
编辑
上述正则表达式不匹配的那些,其与aa
或bb
启动,例如像-aabc-
。要照顾,我们可以添加-
到喜欢向前看符号,
>>> re.findall(r'-(?!aa-|bb-)([^-]+)', string)
仅供参考:'(?!aa | bb)'lookahead不允许那些* aa或bb开头的匹配项。所以说,'aacn' [不会匹配](https://regex101.com/r/jR5sH1/1)。 –
@WiktorStribiżew有效点。我为答案添加了一个编辑。感谢您指出:) – nu11p01n73R
是的,我只是认为最后的'-'实际上是必需的 - 只是由OP输入字符串来判断。如果最后没有'-',你的正则表达式会返回一个匹配,我的不会。这一点尚不清楚,但我猜得到了一个倒退。 –
您需要使用负向前视来限制更一般的模式,并且需要使用re.findall
来查找所有匹配项。
使用
res = re.findall(r'-(?!(?:aa|bb)-)(\w+)(?=-)', s)
或 - 如果您在连字符之间的值可以是任何而是一个连字符,请使用否定的字符类[^-]
:
res = re.findall(r'-(?!(?:aa|bb)-)([^-]+)(?=-)', s)
这里是regex demo。
详细:
-
-
- 一个连字符 -
(?!(?:aa|bb)-)
- 如果第一个连字符后aa-
或bb-
,不匹配应退还 -
(\w+)
- 第1组(该值将由re.findall
呼叫返回)捕获1个或更多字词或[^-]+
- 1个或更多字符除了-
-
(?=-)
- 字符后面必须有一个-
。在这里需要预先保证重叠匹配(因为这个连字符将成为下一场比赛的起点)。
import re
p = re.compile(r'-(?!(?:aa|bb)-)([^-]+)(?=-)')
s = "-a-bc-aa-def-bb-ghij-"
print(p.findall(s)) # => ['a', 'bc', 'def', 'ghij']
我会在这里也加上这句话:我认为最后一次比赛是必须的,因为最后一场比赛只有跟着'-'才有效。这是从OP字符串中推导出来的,所以不太确定。 –
虽然正则表达式溶液要求,我认为这个问题可以用更简单的Python函数,即字符串分割和过滤来解决简单:
input_list = "-a-bc-aa-def-bb-ghij-"
exclude = set(["aa", "bb"])
result = [s for s in input_list.split('-')[1:-1] if s not in exclude]
此解决方案有额外的优点result
也可以变成一台发电机和结果列表并不需要显式地构建。
你想['findall'](https://docs.python.org/2/library/re.html#re.findall) - 'search'只能返回第一个匹配:) – cxw