我需要找到匹配模式的所有字符串,但两个给定的字符串除外。
例如,查找除aa
和bb
之外的所有字母组。从这个字符串开始:
-a-bc-aa-def-bb-ghij-
应该返回:
('a', 'bc', 'def', 'ghij')
我尝试使用捕获4个字符串的this regular表达式。我以为我已经接近了,但(1)它在Python中不起作用,(2)我无法弄清楚如何从搜索中排除一些字符串。 (是的,我可以在以后删除它们,但我真实的正则表达式一次性完成所有操作,我想在其中包含最后一步。)
我说它在Python中不起作用,因为我试过这个,期望完全相同的结果,但我得到的只是第一组:
>>> import re
>>> re.search('-(\w.*?)(?=-)', '-a-bc-def-ghij-').groups()
('a',)
我试着用负面向前看,但我找不到适合这种情况的解决方案。
答案 0 :(得分:6)
你可以利用负向前瞻。
例如,
>>> re.findall(r'-(?!aa|bb)([^-]+)', string)
['a', 'bc', 'def', 'ghij']
-
匹配-
(?!aa|bb)
否定前瞻,检查-
或aa
bb
([^-]+)
匹配除-
修改强>
以上正则表达式与以aa
或bb
开头的正则表达式不匹配,例如-aabc-
。为了解决这个问题,我们可以将-
添加到前瞻中,例如
>>> re.findall(r'-(?!aa-|bb-)([^-]+)', string)
答案 1 :(得分:2)
您需要使用否定前瞻来限制更通用的模式,并使用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']
答案 2 :(得分:0)
虽然要求使用正则表达式解决方案,但我认为使用更简单的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
也可以转换为生成器,结果列表不需要显式构造。