从模式中解析元素

时间:2011-11-21 23:27:18

标签: python regex

我试图解析自然语言解析器(斯坦福解析器)的结果输出。 部分结果如下:

dep(Company-1, rent-5')
conj_or(rent-5, share-10)
amod(information-12, personal-11)
prep_about(rent-5, you-14)
amod(companies-20, non-affiliated-19)
aux(provide-23, to-22)
xcomp(you-14, provide-23)
dobj(provide-23, products-24)
aux(requested-29, 've-28)

我想要获得的结果是:

['dep', 'Company', 'rent']
['conj_or', 'rent', 'share']
['amod', 'information', 'personal']
...
['amod', 'companies', 'non-affiliated']
...
['aux', 'requested', "'ve"]

首先,我尝试直接获取这些元素,但失败了。 然后我意识到正则表达式应该是正确的前进方式。

但是,我对正则表达式完全不熟悉。通过一些探索,我得到了:

m = re.search('(?<=())\w+', line)
m2 =re.search('(?<=-)\d', line)

并且卡住了。

第一个可以正确地获得第一个元素,例如'dep''amod''conj_or',但实际上我还没弄清楚它为何有效......

第二行试图获得第二个元素,例如'Company''rent''information',但我只能在单词后面输入数字。我无法弄清楚如何看待而不是向后看...

顺便说一句,我也无法弄清楚如何处理'non-affiliated'"'ve"等异常。

任何人都可以提供一些提示或帮助。非常感谢。

3 个答案:

答案 0 :(得分:1)

以下是您正在寻找的内容: ([\w-]*)\(([\w-]*)-\d*, ([\w-]*)-\d*\)

[\w-]*周围的括号用于分组,因此您可以访问数据:

ex = r'([\w-]*)\(([\w-]*)-\d*, ([\w-]*)-\d*\)'
m = re.match(ex, line)
print(m.group(0), m.group(1), m.group(2))

顺便说一句,我建议使用Python + PyQT编写的“Kodos”程序来学习和测试正则表达式。这是我最喜欢的测试正则表达式的工具。

答案 1 :(得分:1)

在不知道可能的全部输出的情况下很难给出最佳答案,但是,这是一个可能的解决方案:

>>> [re.findall(r'[A-Za-z_\'-]+[^-\d\(\)\']', line) for line in s.split('\n')]
[['dep', 'Company', 'rent'], 
 ['conj_or', 'rent', 'share'], 
 ['amod', 'information', 'personal'], 
 ['prep_about', 'rent', 'you'], 
 ['amod', 'companies', 'non-affiliated'], 
 ['aux', 'provide', 'to'], 
 ['xcomp', 'you', 'provide'], 
 ['dobj', 'provide', 'products'], 
 ['aux', 'requested', "'ve"]]

它的工作原理是找到所有连续字母组([A-Za-z]代表大写字母A和Z之间的间隔以及小a和z)或字符“_”和“'”在同一行中。

此外,它强制执行以下规则:匹配的字符串在最后位置不得包含给定的字符列表([^...]的语法是“不得包含任何字符(替换”......)用字符列表))。

字符\将转义那些字符,例如“(”或“)”,否则将由正则表达式引擎解析为指令。

最后,s是您在问题中提供的示例字符串...

HTH!

答案 2 :(得分:1)

如果解析器的结果与建议的一样,则可能没有必要使用正则表达式:

from pprint import pprint

source = """
dep(Company-1, rent-5')
conj_or(rent-5, share-10)
amod(information-12, personal-11)
prep_about(rent-5, you-14)
amod(companies-20, non-affiliated-19)
aux(provide-23, to-22)
xcomp(you-14, provide-23)
dobj(provide-23, products-24)
aux(requested-29, 've-28)
"""

items = []

for line in source.splitlines():
    head, sep, tail = line.partition('(')
    if head:
        item = [head]
        head, sep, tail = tail.strip('()').partition(', ')
        item.append(head.rpartition('-')[0])
        item.append(tail.rpartition('-')[0])
        items.append(item)

pprint(items)

输出:

[['dep', 'Company', 'rent'],
 ['conj_or', 'rent', 'share'],
 ['amod', 'information', 'personal'],
 ['prep_about', 'rent', 'you'],
 ['amod', 'companies', 'non-affiliated'],
 ['aux', 'provide', 'to'],
 ['xcomp', 'you', 'provide'],
 ['dobj', 'provide', 'products'],
 ['aux', 'requested', "'ve"]]