首页 > 解决方案 > 正则前瞻和后瞻正则表达式模式

问题描述

我有一个看起来像的文件:

maar beroepsmensen
    p( maar | <s> )     =  0.005859305 [ -2.232154 ]
    p( beroepsmensen | maar ...)    =  7.865118e-06 [ -5.104295 ] # <- first match: 7.865118e-06
    p( kunnen | beroepsmensen ...)  =  6.842439e-08 [ -5.104295 ]
    p( </s> | kunnen ...)   =  0.04018713 [ -1.395913 ]
1 sentences, 2 words, 0 OOVs
0 zeroprobs, logprob= -8.732362 ppl= 814.3052 ppl1= 23237.04

dan scootermobiel
    p( dan | <s> )  =  0.005859305 [ -2.232154 ]
    p( scootermobiel | dan)     =  0.827746 [ -9.106363 ] # <- second match: 0.827746
    p( he | scootermobiel)  =  0.2520393 [ -3.123365 ]
    p( </s> | he ...)   =  0.04499642 [ -1.346822 ]
1 sentences, 2 words, 0 OOVs

和一个包含一些单词的列表,例如mylst = ['beroepsmensen', 'scootermobiel']

我想遍历列表并找到带有模式的行中的第一个数字p( ithwordfromlist | anotherword ) = 9.999999999。(有关 toyexample 的匹配项,请参见上文)。请注意,后面的另一个词|可以接三个点,并且数字有时由一个e-结构组成。

到目前为止,我确实编写了一个正则表达式,它使用正向前瞻来查找前面的所有数字,[其中包含可选.和可选:e-

\d+(\.\d+)?(e-\d+)?(?=( )+\[) #the number of spaces after the number can vary too.

但是,我没有写出与数字前的模式相匹配的正面回溯。例如,lookbehind like(?<=\=( )+)会引发错误A quantifier inside a lookbehind make it non-fixed width。(也许使用lookbehind并不是最好的方法,所以请不要犹豫提出其他解决方案。)

到目前为止,我将长文件拆分为行列表,并将正则表达式应用于该列表中的每个元素。但是,我当然也可以将它应用于整个列表,如果它会更快的话。因此,如果您对这两种方法都有解决方案,请告诉我,然后我将比较运行时。谢谢!!!

编辑:插入以结构开头p( word1 | word2 )且不应匹配的新行

Edit2:使问题更具体

标签: pythonregexregex-lookarounds

解决方案


像这样的正则表达式怎么样:

\s*p\s*\(\s*\w+\s*\|\s*\w+\s*\)\s*=\s*([\de\-\.]+)\s*\[\s*[\-\.\de]+\s*\]\s*

如此处所见

您需要做的就是从每场比赛中提取第 1 组。

完整的代码如下所示:

import re

pattern = r'\s*p\s*\(\s*\w+\s*\|\s*\w+\s*\)\s*=\s*([\de\-\.]+)\s*\[\s*[\-\.\de]+\s*\]\s*'

f = """maar beroepsmensen
    p( maar | <s> )     =  0.005859305 [ -2.232154 ]
    p( beroepsmensen | maar )    =  7.865118e-06 [ -5.104295 ] # <- first match: 7.865118e-06
    p( </s> | beroepsmensen ...)    =  0.04018713 [ -1.395913 ]
1 sentences, 2 words, 0 OOVs
0 zeroprobs, logprob= -8.732362 ppl= 814.3052 ppl1= 23237.04

dan scootermobiel
    p( dan | <s> )  =  0.005859305 [ -2.232154 ]
    p( scootermobiel | dan)     =  0.827746 [ -9.106363 ] # <- second match: 0.827746
    p( </s> | scootermobiel ...)    =  0.04499642 [ -1.346822 ]
1 sentences, 2 words, 0 OOVs"""

print(re.findall(pattern, f))

输出将是['7.865118e-06', '0.827746']


推荐阅读