4

我正在尝试使用正则表达式查找子字符串的所有出现。子串由三部分组成,以一个或多个'A'开始,后接一个或多个'N',以一个或多个'A'结束。让一个字符串'AAANAANABNA',如果我解析字符串,我应该得到两个子字符串'AANAA''AANA'作为输出。所以,我尝试了下面的代码。

import regex as re
reg_a='A+N+A+'
s='AAANAANABNA'
sub_str=re.findall(reg_a,s,overlapped=True)
print(sub_str)

而且,我得到以下输出,

['AAANAA', 'AANAA', 'ANAA', 'AANA', 'ANA']

但是,我希望输出为,

['AAANAA', 'AANA']

也就是说,第一场比赛的尾随A应该是下一场比赛的领先A。我怎么能得到那个,知道吗?

4

3 回答 3

4

这是使用re模块实现此目的的更简单方法。我们只需要对 1+ 尾随As 进行前瞻,并且必须使用 2 个捕获组:

>>> import re
>>> s = 'AAANAANABNA'
>>> [''.join(x) for x in re.findall(r'(A+N+)(?=(A+))', s)]
['AAANAA', 'AANA']

正则表达式演示

于 2020-06-16T20:05:30.253 回答
4

确保A左侧没有:

>>> reg_a='(?<!A)A+N+A+'
>>> print( re.findall(reg_a,s,overlapped=True) )
['AAANAA', 'AANA']

(?<!A)A+N+A+比赛_

  • (?<!A)- 与未紧随其后的位置匹配的负面回溯A
  • A+- 一个或A多个
  • N+- 一个或N多个
  • A+- 一个或A多个

请注意,您也可以使用它re来获取匹配项:

>>> import re
>>> re_a = r'(?=(?<!A)(A+N+A+))'
>>> print( re.findall(re_a, s) )
['AAANAA', 'AANA']
于 2020-06-16T19:57:58.583 回答
4

一种选择是在没有重叠的情况下,在正前瞻内使用带有捕获组的负后瞻。re.findall 将返回捕获组的值。

(?=(?<!A)(A+N+A+))
  • (?=正向前瞻,断言右边是
    • (?<!A)负前瞻,断言左边不是 A
    • (A+N+A+)匹配你的模式
  • )关闭前瞻

正则表达式演示| Python 演示

import re
s = "AAANAANABNA"
pattern = r"(?=(?<!A)(A+N+A+))"
print(re.findall(pattern, s))

输出

['AAANAA', 'AANA']

或者按照@anubhava的建议,将后视与前瞻分开:

(?<!A)(?=(A+N+A+))

正则表达式演示| Python 演示

于 2020-06-16T19:59:02.493 回答