我有一个字符串的格式:
my_string = 'hello|foo world|foo how|bar are|bar you|bar today|foo'
我想返回一个列表,其中后面跟着foo的所有连续单词在同一个字符串中分组在一起,但是单词之间有一个'|bar'单词在单独的字符串中。如果我尝试重复向前看:
re.findall(r'(w+(?=|foob))+',my_string)
返回['hello', 'world', 'today']
但是我想返回的是
['hello world', 'today']
因为'hello'和'world'之间没有非foo字分隔。
在我的实际问题中,'foo'后面的单词序列在被搜索的字符串中出现的次数是未知的,'bar'可能是几种不同的模式。
我可以用几个替换来解决它,首先用split指示符替换所有非foo模式并在其上分割,然后删除foo并剥离空间:
bars_removed = re.sub('(w+|(?!foo)[a-z]+ )+','split_string',my_string)
only_foo_words = [re.sub('|foo','',x).strip() for x in bars_removed.split('split_string')]
返回所需的结果,但我觉得有一种方法可以使用findall或我遗漏的finditer来实现这一点。
你不能"排除"在同一组中捕获的其他文本之间的文本。
您需要用消费模式替换forward,提取所有连续的匹配,然后用仅仅str.replace
方法删除|foo
作为后处理步骤。
final_list = [x.replace('|foo','') for x in re.findall(r'w+|foo(?:s+w+|foo)*', my_string)]
参见regex演示。
细节:
w+
-一个或多个字字符|foo
- a|foo
字符串(?:s+w+|foo)*
-匹配0个或多个序列的非捕获组s+
-一个或多个空白w+|foo
-一个或多个字字符,然后是|foo
字符串。