修复python元组正则表达式时出现问题?

修复python元组正则表达式时出现问题?,python,regex,list,python-2.7,encoding,Python,Regex,List,Python 2.7,Encoding,我有一个很大的.txt文件,它由以下部分组成:word1,word2,id,number,如下所示: s = ''' Vaya ir VMM03S0 0.427083 mañanita mañana RG 0.796611 , , Fc 1 buscando buscar VMG0000 1 una uno DI0FS0 0.951575 lavadora lavadora NCFS000 0.414738 con con SPS00 1 la el DA0FS0 0.972269 que qu

我有一个很大的
.txt
文件,它由以下部分组成:
word1
word2
id
number
,如下所示:

s = '''
Vaya ir VMM03S0 0.427083
mañanita mañana RG 0.796611
, , Fc 1
buscando buscar VMG0000 1
una uno DI0FS0 0.951575
lavadora lavadora NCFS000 0.414738
con con SPS00 1
la el DA0FS0 0.972269
que que PR0CN000 0.562517
sorprender sorprender VMN0000 1
a a SPS00 0.996023
una uno DI0FS0 0.951575
persona persona NCFS000 0.98773
muy muy RG 1
especiales especial AQ0CS0 1
para para SPS00 0.999103
nosotros nosotros PP1MP000 1
, , Fc 1
y y CC 0.999962
la lo PP3FSA00 0.0277039
encontramos encontrar VMIP1P0 0.65
. . Fp 1

Pero pero CC 0.999764
vamos ir VMIP1P0 0.655914
a a SPS00 0.996023
lo el DA0NS0 0.457533
que que PR0CN000 0.562517
interesa interesar VMIP3S0 0.994868
LO_QUE_INTERESA_La lo_que_interesa_la NP00000 1
lavadora lavador AQ0FS0 0.585262
tiene tener VMIP3S0 1
una uno DI0FS0 0.951575
clasificación clasificación NCFS000 1
A+ a+ NP00000 1
, , Fc 1
de de SPS00 0.999984
las el DA0FP0 0.970954
que que PR0CN000 0.562517
ahorran ahorrar VMIP3P0 1
energía energía NCFS000 1
, , Fc 1
si si CS 0.99954
no no RN 0.998134
me me PP1CS000 0.89124
equivoco equivocar VMIP1S0 1
. . Fp 1

Lava lavar VMIP3S0 0.397388
hasta hasta SPS00 0.957698
7 7 Z 1
kg kilogramo NCMN000 1
, , Fc 1
no no RN 0.998134
está estar VAIP3S0 0.999201
nada nada RG 0.135196
mal mal RG 0.497537
, , Fc 1
se se P00CN000 0.465639
le le PP3CSD00 1
veía ver VMII3S0 0.62272
un uno DI0MS0 0.987295
gran gran AQ0CS0 1
tambor tambor NCMS000 1
( ( Fpa 1
de de SPS00 0.999984
acero acero NCMS000 0.973481
inoxidable inoxidable AQ0CS0 1
) ) Fpt 1
y y CC 0.999962
un uno DI0MS0 0.987295
consumo consumo NCMS000 0.948927
máximo máximo AQ0MS0 0.986111
de de SPS00 0.999984
49 49 Z 1
litros litro NCMP000 1
Mandos mandos NP00000 1
intuitivos intuitivo AQ0MP0 1
, , Fc 1
todo todo PI0MS000 0.43165
muy muy RG 1
bien bien RG 0.902728
explicado explicar VMP00SM 1
, , Fc 1
nada nada PI0CS000 0.850279
que que PR0CN000 0.562517
ver ver VMN0000 0.997382
con con SPS00 1
hola RG 0.90937838
como VMP00SM 1
estas AQ089FG 0.90839
la el DA0FS0 0.972269
lavadora lavadora NCFS000 0.414738
de de SPS00 0.999984
casa casa NCFS000 0.979058
de de SPS00 0.999984
mis mi DP1CPS 0.995868
padres padre NCMP000 1
Además además NP00000 1
también también RG 1
seca seco AQ0FS0 0.45723
preciadas preciar VMP00PF 1
. . Fp 1'''
例如,对于
s
“文件”,我想提取
id
,它们以
AQ
RG
开头,然后是它们的
word2
,但是它们必须依次出现,因为上面的示例这些单词保持一个接一个的顺序

muy muy RG 1
especial especial AQ0CS0 1
对于示例,这些单词不具有一个接一个的顺序,因此我不想将它们提取到元组中:

hola RG 0.90937838
como VMP00SM 1
estas AQ089FG 0.90839
我想创建一个正则表达式,它在元组列表中只提取
word2
,然后是它的
id
,如下所示:
[('word2','id')]
,用于所有.txt文件和一个接一个顺序为true的所有单词对于上述示例,这是唯一有效的输出:

muy muy RG 1
especiales especial AQ0CS0 1

然后返回一个元组,其中包含完整的
id
,因为它们保留了一个接一个的顺序:

[('muy', 'RG', 'especial', 'AQ0CS0'), ('también', 'RG', 'seco', 'AQ0FS0')]
我尝试了以下方法:

在:

但是我的输出是错误的,因为它删除了重音和一些字符:

muy muy RG 1
especiales especial AQ0CS0 1
输出:

而不是,哪一个是正确的:

[('muy', 'RG', 'especial', 'AQ0CS0'), ('también', 'RG', 'seco', 'AQ0FS0')]

有人能帮我理解我上面的例子发生了什么,以及如何修复它,以便捕捉保存一个又一个事件的
word2
id
?。提前感谢各位。

如果希望包含完整的ID,请将其添加到正则表达式中:

re.findall(r'^(\w+)\s.+\s(RG)\s[0-9.]+\n(.+)\s.+\s(AQ[A-Z0-9]+)', s, re.M)
请注意,
\w
类与非ASCII字符不匹配。将
s
解码为
unicode
并使用unicode正则表达式:

re.findall(r'^(\w+)\s.+\s(RG)\s[0-9.]+\n(.+)\s.+\s(AQ[A-Z0-9]+)',
    s.decode('utf8'), re.M | re.UNICODE)
用于解码的编解码器取决于您的输入文件;我选择UTF-8作为例子,但这并不一定正确

演示:


你的尝试对我有效;给定此处发布的
s
,您的
re.findall()
返回
[('muy','RG','speciales','AQ'),('muy','RG','sencilla','AQ')]
。你确定
s
反映了现实吗?你真的需要正则表达式吗?或者一个冗长的程序可以吗?如果
s
是一个
unicode
字符串,您需要在标志中包含
re.unicode
,以确保
\w
匹配的不仅仅是ASCII字字符,但是您给定的
s
没有使用ASCII以外任何东西的潜在匹配项。@MartijnPieters感谢您的反馈。我必须返回完整的
id
,所以我错了。另一方面,我正在从
.txt
文件中读取内容。我不知道为什么我会得到一个空列表。你知道怎么解决这个问题吗?。Thanks@quickbug我不知道如何使用程序(解析器、lexer,也许?)来实现这一点。我想只要一个正则表达式就可以轻松完成。谢谢你的支持,谢谢你的帮助。您认为这个正则表达式是否适用于
AQ
后跟
RG
模式?@newWithPython:您可以使用相同的技术,只需交换模式。我必须说,我正在执行以下操作,以便为目录中的所有
.txt
文件检索此模式:检查更新:***编辑**可能这就是此正则表达式不起作用的原因。@newWithPython我们看不到文件中的内容。该技术适用于您的样品;您必须找出
s
与实际文件内容之间的区别。是否可以创建与所需输出匹配的正则表达式,而不使用
re.M
标志?。谢谢
re.findall(r'^(\w+)\s.+\s(RG)\s[0-9.]+\n(.+)\s.+\s(AQ[A-Z0-9]+)', s, re.M)
re.findall(r'^(\w+)\s.+\s(RG)\s[0-9.]+\n(.+)\s.+\s(AQ[A-Z0-9]+)',
    s.decode('utf8'), re.M | re.UNICODE)
>>> re.findall(r'^(\w+)\s.+\s(RG)\s[0-9.]+\n^(.+)\s.+\s(AQ[A-Z0-9]+)',
...     s.decode('utf8'), re.M | re.UNICODE)
[(u'muy', u'RG', u'especiales', u'AQ0CS0'), (u'muy', u'RG', u'sencilla', u'AQ3948')]
def code(aline):
    try:
        a,b,c,d = aline.split()
        return c[:2]
    except ValueError:
        return ''

result = []
l2 = ''
with open('texte.txt') as fp:
    for l3 in fp:
        l1, l2 = l2, l3
        if code(l1)=='RG' and code(l2)=='AQ':
            a,b,c,d = l1.split()
            e,g,h,j = l2.split()
            result.append((a, c, e, h))
print(result)