我在使用PyParsing时遇到了一些麻烦。我需要从简历中解析一些书目信息。一个例子:
AuthorA,B.,AuthorB,M.R。,AuthorC,V.,and B. LastAuthor。一些 科技称号。会议名称,城市,州,2012年12月3日
我想出了一些代码来解析(主要是)作者列表和日期......其他信息对我来说并不是特别重要。
from pyparsing import (Word, Literal, OneOrMore, alphanums, delimitedList, printables,
alphas, nums)
family_name = Word(alphanums+'-')
first_init = Word(alphanums+'.')
author = (family_name("LastName") + Literal(',').suppress() +
OneOrMore(first_init("FirstInitials") ) )
last_author = first_init("FirstInitials") + family_name("LastName")
author_list = delimitedList(author) + Literal('and').suppress() + last_author
sentence = OneOrMore(Word(printables))
location = delimitedList(Word(printables))
date = Word(alphas) + Word(nums) + Literal(',').suppress() + Word(nums)
citation = (author_list('AuthorLst') + sentence('Title') + location('Location')
+ date('Date'))
citation.parseString(ntext)
然而,它放在"和"作为作者列表和最后一位作者之间的区别。
我收到错误消息:
---------------------------------------------------------------------------
ParseException Traceback (most recent call last)
<ipython-input-142-5d7946dcb775> in <module>()
15
16
---> 17 citation.parseString(ntext)
/Users/willdampier/anaconda/lib/python2.7/site-packages/pyparsing.pyc in parseString(self, instring, parseAll)
1123 else:
1124 # catch and re-raise exception from here, clears out pyparsing internal stack trace
-> 1125 raise exc
1126 else:
1127 return tokens
ParseException: Expected "and" (at char 40), (line:1, col:41)
有什么建议吗?
答案 0 :(得分:3)
定义author
后,添加以下行:
author.setName("author").setDebug()
跟踪author
表达式的匹配。然后,为了获得更好的整体诊断,请将测试线更改为:
author_list.runTests(ntext)
通过这些更改,您将获得如下输出:
Match author at loc 0(1,1)
Matched author -> ['AuthorA', 'B.']
Match author at loc 12(1,13)
Matched author -> ['AuthorB', 'M.', 'R.']
Match author at loc 28(1,29)
Matched author -> ['AuthorC', 'V.']
Match author at loc 41(1,42)
Exception raised:Expected "," (at char 46), (line:1, col:47)
AuthorA, B., AuthorB, M. R., AuthorC, V., and B. LastAuthor. Some sciency title. Name of the confernce, City, State, December 3, 2012
^
FAIL: Expected "and" (at char 40), (line:1, col:41)
所以你当前的问题是你没有处理尾随&#39;&#39;在&#39;和&#39;之前。您还需要添加尾随&#39;。&#39;您对author_list
。
但是从那里开始,sentence
的解析器会有问题,因为它将处理整个字符串的其余部分。由于您的主要兴趣是获取日期,因此这可能适合您:
stuff = OneOrMore(Word(printables), stopOn=date)
citation = (author_list('AuthorLst') + stuff('body') + date('Date'))
最后,关于您对结果名称的使用(&#34; FirstInitials&#34;,&#34; LastName&#34;等)。干得好,这是一个功能 在pyparsing中我特别满意。但是你需要对每个作者引用中的名称进行一些隔离, 否则你只能得到最后一位作者的名字。为此,请将每个作者包装在一个pyparsing Group中:
author = Group(family_name("LastName") + Literal(',').suppress() +
OneOrMore(first_init("FirstInitials") ) )
last_author = Group(first_init("FirstInitials") + family_name("LastName"))
现在,您的author_list
应该会为您提供子结构列表。如果你这样做,你可以看到它们:
print(citation.parseString(ntext).dump())
通过我的更改,我得到了您的示例文本:
[['AuthorA', 'B.'], ['AuthorB', 'M.', 'R.'], ['AuthorC', 'V.'], ',',
['B.', 'LastAuthor'], '.', 'Some', 'sciency', 'title.', 'Name', 'of',
'the', 'confernce,', 'City,', 'State,', 'December', '3', '2012']
- AuthorLst: [['AuthorA', 'B.'], ['AuthorB', 'M.', 'R.'],
['AuthorC', 'V.'], ',', ['B.', 'LastAuthor'], '.']
[0]:
['AuthorA', 'B.']
- FirstInitials: 'B.'
- LastName: 'AuthorA'
[1]:
['AuthorB', 'M.', 'R.']
- FirstInitials: 'R.'
- LastName: 'AuthorB'
[2]:
['AuthorC', 'V.']
- FirstInitials: 'V.'
- LastName: 'AuthorC'
[3]:
,
[4]:
['B.', 'LastAuthor']
- FirstInitials: 'B.'
- LastName: 'LastAuthor'
[5]:
.
仍然需要压制&#39;,&#39;和&#39;。&#39;标点符号,但这只是清理。然后你就可以轻松了 迭代您的作者列表并获取每个作者的姓名。