正则表达式有问题吗?

2024-05-23 19:22:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个very_largeString,它包含一个单词和一些id的列表。我想提取所有在形态上连续出现的RGAQ的单词(以及它们的id),并打印剩余的id。输出就是单词和它的相关id例如:[('word','id'),('word','id')]

very_largeString= ''' Hola hola I 1
compis compis NCMS000 0.500006
! ! Fat 1

No no RN 0.998045
sabía saber VMII3S0 0.592869
como como CS 0.999289
se se P00CN000 0.465639
ponía poner VMII3S0 0.65
una uno DI0FS0 0.951575
lavadora lavadora NCFS000 0.414738
hasta hasta SPS00 0.957698
que que PR0CN000 0.562517
conocí conocer VMIS1S0 1
esta este DD0FS0 0.986779
y y CC 0.999962
muy muy RG 1
sencilla malo AQ0MP0
es ser VSIP3S0 1
que que CS 0.437483
es ser VSIP3S0 1
muy muy RG 1
sencilla sencillo AQ0FS0 1
de de SPS00 0.999984
utilizar utilizar VMN0000 1
! ! Fat 1    
'''

这将是所需的输出,因为它们在id的begining处有RG和AQ字符,所以我想返回完整的id,例如:

[('muy', RG), ('sencillo', 'AQ0FS0'),('muy'),('malo','AQ0MP0')]

问题是我得到了一个空输出。这就是我所尝试的:

result = re.findall("(\S+)\s+(RG\S+).*\n.*\s(\S+)\s+(AQ\S+)",very_largeString)

有人能帮我修一下这个正则表达式吗?,我不知道为什么错了。你知道吗


Tags: idcs单词fatwordveryrgque
3条回答

您的主要问题是RG\S+不匹配RG 1,因为该空格不匹配一个或多个非空格字符。我想你想要\s+那里?(或者\S*?但是我没有看到任何RG1类型的匹配。或者什么都没有,因为我不确定任何子模式在这里试图做什么?)你知道吗

(\S+)\s+(RG\s+).\n.*\s(\S+)\s+(AQ\S+)

Regular expression visualization

Debuggex Demo

但是,这并不能提供所需的输出。它给你的是:

[('muy', 'RG ', 'malo', 'AQ0MP0'), ('muy', 'RG ', 'sencillo', 'AQ0FS0')]

'RG '很明显,你试图在RG之后匹配一些必须的东西,而在RG之后唯一的东西就是一个空格,那么你还能得到什么呢?你知道吗

您似乎还希望分别匹配第一行和第二行,这是可行的,但只能使用一个包含lookaheads和lookbehinds的极其复杂的表达式,并且只需对列表进行后期处理就简单得多。你知道吗

你似乎也希望这两对按相反的顺序排列。我想这在理论上是可能的,但我完全不知道你是怎么开始这么做的,我怀疑任何有效的方法都需要指数级的时间,通过后处理要简单得多。你知道吗

最后,出于某种原因,您希望第二对只匹配('muy'),而不是('muy', 'RG'),这(a)没有任何意义,因为('muy')不是一个1项元组,它只是字符串'muy',(b)我不知道你第一次怎么能把两件东西搭配起来,但第二次只能把一件东西搭配成完全相同的图案和同一条线。你知道吗

假设您的大多数需求实际上都不是真实的,您唯一想做的就是将它们从4s重新组合为2s,如下所示:

[('muy', 'RG'), ('malo', 'AQ0MP0'), ('muy', 'RG'), ('sencillo', 'AQ0FS0')]

…我将\s+移出正则表达式,并将结果从4组后处理为2组,如下所示:

result = re.findall(r"(\S+)\s+(RG)\s+.*\n.*\s(\S+)\s+(AQ\S+)",very_largeString)
flattened = (x for y in result for x in y)
paired = list(zip(flattened, flattened))

如果你调整它,像这样
(\S+)\s+(RG\S*).*\n.*[^\S\n](\S+)[^\S\n]+(AQ\S*)
会得到你期望的结果。你知道吗

 ( \S+ )          # (1)
 \s+ 
 ( RG \S* )       # (2)
 .* \n 
 .* [^\S\n] 
 ( \S+ )          # (3)
 [^\S\n]+ 
 ( AQ \S* )       # (4)

输出:

 **  Grp 0 -  ( pos 358 , len 29 ) 
muy RG 1
sencilla malo AQ0MP0  
 **  Grp 1 -  ( pos 358 , len 3 ) 
muy  
 **  Grp 2 -  ( pos 362 , len 2 ) 
RG  
 **  Grp 3 -  ( pos 376 , len 4 ) 
malo  
 **  Grp 4 -  ( pos 381 , len 6 ) 
AQ0MP0  

            

 **  Grp 0 -  ( pos 446 , len 33 ) 
muy RG 1
sencilla sencillo AQ0FS0  
 **  Grp 1 -  ( pos 446 , len 3 ) 
muy  
 **  Grp 2 -  ( pos 450 , len 2 ) 
RG  
 **  Grp 3 -  ( pos 464 , len 8 ) 
sencillo  
 **  Grp 4 -  ( pos 473 , len 6 ) 
AQ0FS0  

我试过了

 re.findall('(\w+\s+)(RG\w*|AQ\w*)',very_largeString)

输出:

[('muy ', 'RG'), ('malo ', 'AQ0MP0'), ('muy ', 'RG'), ('sencillo ', 'AQ0FS0')]

如果要删除重复项,可以使用set

相关问题 更多 >