Python 使用pyparsing解析名称
我有一个名字和年龄的档案Python 使用pyparsing解析名称,python,pyparsing,Python,Pyparsing,我有一个名字和年龄的档案 john 25 bob 30 john bob 35 这是我到目前为止所拥有的 from pyparsing import * data = ''' john 25 bob 30 john bob 35 ''' name = Word(alphas + Optional(' ') + alphas) rowData = Group(name + Suppress(White(" ")) +
john 25
bob 30
john bob 35
这是我到目前为止所拥有的
from pyparsing import *
data = '''
john 25
bob 30
john bob 35
'''
name = Word(alphas + Optional(' ') + alphas)
rowData = Group(name +
Suppress(White(" ")) +
Word(nums))
table = ZeroOrMore(rowData)
print table.parseString(data)
我期望的结果是
[['john',25],'bob',30],'john bob',35]
这是stacktrace
Traceback (most recent call last):
File "C:\Users\mccauley\Desktop\client.py", line 11, in <module>
eventType = Word(alphas + Optional(' ') + alphas)
File "C:\Python27\lib\site-packages\pyparsing.py", line 1657, in __init__
self.name = _ustr(self)
File "C:\Python27\lib\site-packages\pyparsing.py", line 122, in _ustr
return str(obj)
File "C:\Python27\lib\site-packages\pyparsing.py", line 1743, in __str__
self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
File "C:\Python27\lib\site-packages\pyparsing.py", line 1735, in charsAsStr
if len(s)>4:
TypeError: object of type 'And' has no len()
回溯(最近一次呼叫最后一次):
文件“C:\Users\mccauley\Desktop\client.py”,第11行,在
eventType=Word(字母+可选(“”)+字母)
文件“C:\Python27\lib\site packages\pyparsing.py”,第1657行,在\uuu init中__
self.name=\u ustr(self)
文件“C:\Python27\lib\site packages\pyparsing.py”,第122行,在ustr中
返回str(obj)
文件“C:\Python27\lib\site packages\pyparsing.py”,第1743行,在__
self.strRepr=“W:(%s)”%charsAsStr(self.initCharsOrig)
charsAsStr中的文件“C:\Python27\lib\site packages\pyparsing.py”,第1735行
如果长度>4:
TypeError:类型为“And”的对象没有len()
pyparsing
自动去除空白,以便编写更干净的语法。因此,您的名称解析器应该更像:
# Parse for a name with an optional surname
# Note that pyparsing is built to accept "john doe" or "john doe"
name = Word(alphas) + Optional(Word(alphas))
然后,行解析器:
# Parses a row of a name and an age
row = Group(name) + Word(nums)
不过,对于每一行,您将得到一个相当复杂的结构,([(['john','doe'],{}),'25'],{})
,但我希望您可以了解如何使用它。我建议不要真正使用pyparsing来解析整个字符串,如果数据是基于行的,则应该逐行迭代地解析它。让事情变得更简单,我认为:
for line in input_string.splitlines():
results = row.parseString(line)
# Do something with results...
以下代码可以使用内置字符串库解决您的问题
def main():
f = open('filename.txt')
fe = open('ERROR.TXT','w+')
for line in f.readlines():
# print line,
lst = line.split()
try:
name = lst[0]
age = lst[1]
# process name and age valuse
except IndexError as e:
print e
fe.write(e)
except IOError as e:
print e
fe.write(e)
if __name__ == '__main__':
main()
我认为你故意选择
pyparsing
作为学习练习?使用内置的字符串函数甚至正则表达式会更好trivial@JonClements实际上,这是一个非常大的项目的一部分,我相信pyparsing比regex更适合这个项目,我真的需要知道如何做单空间的事情。我希望。请看我对这个问题的评论。只有当你把它打印出来时,结构才显得复杂。事实上,该结构是一个ParseResults,可以像嵌套列表一样进行迭代,或者如果任何元素都有结果名,则可以像dict一样通过键进行访问。由于您已经Group
ed了前导名称(做得很好,顺便说一句),您甚至可以像name,age=results那样进行元组解压缩。如果将行更改为row=Group(name)('name')+Word(nums)('age')
,则可以使用results.age
或results['age']
按名称访问结果,这在表达式中也有可选元素时非常有用。@PaulMcGuire如果我没有弄错(如果我错了请纠正我!),有.scanString
来处理输入字符串中的行。splitlines():
问题。也就是说,它创建了一个迭代器,该迭代器生成语法的单个过程的输出。因此,您可以将其替换为类似于的内容,以获得行中的结果。scanString():
。Close-scanString
返回一个生成器,该生成器为找到的每个匹配项生成一个(标记、开始、结束)
元组searchString
只是scanString
,[令牌的令牌,在expr.scanString中开始,结束]
。