如何修复此正则表达式以保留特定的优先顺序?

How to fix this regex in order to preserve an specific precedence order?

我有一个由两个词和一个 id 组成的大字符串:

large_string = '''

Aparte aparte RG 0.910714
tiene tener VMIP3S0 1
muy muy RG 1
buena bueno AQ0FS0 1
dimension dimension VMIS3P0 0.923476
me me PP1CS000 0.89124
entra entrar VMIP3S0 0.980769
casi casi RG 1
toda todo DI0FS0 0.982026
una uno DI0FS0 0.951575
bolsa bolsa NCFS000 1
de de SPS00 0.999984
consorcio consorcio NCMS000 1
entera entero AQ0FS0 0.841237
de de SPS00 0.999984
ropa ropa NCFS000 1
. . Fp 1

El el DA0MS0 1
manual manual NCMS000 0.64261
instructivo instructivo AQ0MS0 1
es ser VSIP3S0 1
bastatnte bastatnte RG 0.557451
específico específico AQ0MS0 0.65727
y y CC 0.999962

我想从左到右提取第二个单词和保留以下顺序的id:

RN, VA_ _ _ _ _, VMP_ _ _ _ _

其中_是id的自由字符。例如,对于 large_string,保留此顺序的单词和 ID 如下:

no no RN 
esta estar VASI1S0 
lavando lavar VMP00SM

所以我想生成一个正则表达式来捕捉这个 id 和单词的顺序,这就是我试过的:

triple = re.findall(r'(\w+\s+RN).*?(\w+\s+VA\w+).*?(\w+\s+VM\w+)', big_string, re.S)
print weird_triple

然后:

[('no RN', 'error VA00SM', 'utilizar VMN0000'), ('error RN', 'alla VASI1S0', 'lavar VMP00SM')]

这个问题是上面的正则表达式没有保留顺序(RN, VA, VMP它们大多数是连续的)。我怎样才能修复它以便只捕获这种类型的连续 word/id。预期输出如下:

您需要使用基于否定前瞻的正则表达式。

>>> re.findall(r'(?s)(\w+\s+RN)(?:(?!\s(?:RN|VA|VM)).)*?(\w+\s+VA\w+)(?:(?!\s(?:RN|VA|VM)).)*?(\w+\s+VM\w+)', large_string)
[('no RN', 'estar VASI1S0', 'lavar VMP00SM')]

DEMO

(?!\s(?:RN|VA|VM)) 断言匹配中不存在字符串 <space> 加上 RAVAVM。如果是,则匹配以下任何字符 (?!\s(?:RN|VA|VM)). ,零次或多次 (?:(?!\s(?:RN|VA|VM)).)*? 非贪婪。