如何让 Python 像 grep 一样重新工作以重复组?

sod*_*ate 6 python regex grep

我有以下字符串:

seq = 'MNRYLNRQRLYNMYRNKYRGVMEPMSRMTMDFQGRYMDSQGRMVDPRYYDHYGRMHDYDRYYGRSMFNQGHSMDSQRYGGWMDNPERYMDMSGYQMDMQGRWMDAQGRYNNPFSQMWHSRQGH'
Run Code Online (Sandbox Code Playgroud)

也保存在一个名为seq.dat. 如果我使用以下grep命令

grep '\([MF]D.\{4,6\}\)\{3,10\}' seq.dat
Run Code Online (Sandbox Code Playgroud)

我得到以下匹配字符串:

MDNPERYMDMSGYQMDMQGRWMDAQGRYN
Run Code Online (Sandbox Code Playgroud)

这就是我想要的。换句话说,我想要匹配的是与字符串相同的连续重复次数[MF]D.{4,6}。我不想匹配连续重复次数少于 3 次的情况,但我希望它能够捕获最多 6 次。

现在,我正在尝试用 python 来做到这一点。我有

p = re.compile("(?:[MF]D.{4,6}){3,10}")
Run Code Online (Sandbox Code Playgroud)

尝试search()退货

MDNPERYMDMSGYQMDMQGRWM
Run Code Online (Sandbox Code Playgroud)

这是接近我寻求的答案,但仍然缺少最后一个MDAQGRYN。我猜这是因为.{4,6}匹配了M,这又阻止{3,10}了捕获第四次出现([MF]D.{4,6}),但由于我要求至少 3 个,它很高兴并且停止了。

如何使 Python 正则表达式像 grep 一样运行?

Wik*_*żew 5

POSIX(“文本导向”)和 NFA(“正则表达式导向”)引擎之间存在根本区别。POSIX 引擎(grep此处使用 POSIX BRE 正则表达式风格,这是默认使用的风格)将解析应用正则表达式的输入文本并返回可能的最长匹配。NFA引擎(Pythonre引擎是NFA引擎)这里当后续模式部分匹配时不会重新消费(回溯)。

\n

请参阅有关正则表达式导向和文本导向引擎的参考

\n
\n

正则表达式引导的引擎遍历正则表达式,尝试将正则表达式中的下一个标记与下一个字符匹配。如果找到匹配项,引擎将继续执行正则表达式和主题字符串。如果令牌无法匹配,引擎将回溯到正则表达式和主题字符串中的前一个位置,在该位置可以尝试通过正则表达式的不同路径...使用正则表达式定向引擎的现代正则表达式风格具有许多功能,例如原子分组以及所有格量词,让您可以控制这种回溯。

\n

文本导向引擎遍历主题字符串,在前进到字符串中的下一个字符之前尝试正则表达式的所有排列。文本导向的引擎永远不会回溯。因此,关于文本导向引擎的匹配过程,\xe2\x80\x99 没有太多可讨论的。在大多数情况下,文本导向引擎会找到与正则表达式导向引擎相同的匹配项。

\n
\n

最后一句说“在大多数情况下”,但不是所有情况,你的例子很好地说明了可能会出现差异。

\n

为了避免消耗MF紧随其后D,我建议使用

\n
(?:[MF]D(?:(?![MF]D).){4,6}){3,10}\n
Run Code Online (Sandbox Code Playgroud)\n

请参阅正则表达式演示细节

\n
    \n
  • (?:- 外部非捕获容器组的开始:\n
      \n
    • [MF]D-MF然后D
    • \n
    • (?:(?![MF]D).){4,6}- 任何字符(换行符除外)重复四到六次,不会启动MDFD字符序列
    • \n
    \n
  • \n
  • ){3,10}- 外组结束,重复3至10次。
  • \n
\n

顺便说一句,如果您只想匹配大写 ASCII 字母,请将 替换.[A-Z]

\n