pyparsing 模糊性
我正在尝试用PyParser来解析一些文本。问题是我的名字中可能会有空格。所以我的输入可能看起来像这样。首先,是一份名字的列表:
Joe
bob
Jimmy X
grjiaer-rreaijgr Y
然后,是他们做的事情:
Joe A
bob B
Jimmy X C
当然,问题在于,他们做的事情可能和名字的结尾是一样的:
Jimmy X X
grjiaer-rreaijgr Y Y
我该如何为这些动作行创建一个解析器呢?解析Joe A
的结果应该是[Joe, A]
。解析Jimmy X C
的结果应该是[Jimmy X, C]
,而Jimmy X X
的结果则是[Jimmy X, X]
。也就是说,结果应该是[名字, 动作]
的配对。
如果我简单地创建一个名字解析器,比如用OneOrMore(RegEx("\S*"))
,那么它会匹配整行,给我[Jimmy X X]
,接着就会出现解析错误,因为它没有看到动作(因为名字解析器已经把它消耗掉了)。
注意:抱歉之前的表述有点模糊,让人觉得这是个自然语言处理的问题。
3 个回答
看起来你需要用nltk,而不是pyparsing。你需要找一个比较简单的问题来练习。你是怎么知道要解析“jimmy foo decides decides to eat”的?你用什么规则来判断(和大多数人想的不同)“decides decides”并不是一个拼写错误呢?
关于“可以包含空格的名字”:首先,我希望你能把它们规范成一个空格。其次:这很意外吗?第三:名字可以包含撇号和连字符(比如O'Brien,Montagu-Douglas-Scott),而且可能有一些部分是小写的,比如Georg von und zu Hohenlohe),还有Unicode就不提了。
你需要的不仅仅是一个简单的解析器。解析器会利用字符串中的符号来判断字符串的不同部分代表语法中的哪些元素。这就是为什么有人会问你怎么知道哪个部分是名字,哪个部分是句子的其他内容。如果你能说名字是由一个或多个大写字母开头的单词组成,那么解析器就能知道名字在哪里结束,句子的其他部分从哪里开始。
但是像“jimmy foo decides”这样的名字呢?解析器怎么能仅仅通过看“decides”这个词的符号来判断它是否是名字的一部分呢?就算是人类在读“jimmy foo decides decides to eat”这句话时,也会有些困惑,不知道名字从哪里开始,在哪里结束,甚至可能觉得这是个打错的字。
如果你的输入真的这么不可预测,那你就需要使用像NLTK(自然语言工具包)这样的工具。我自己没有用过,但它是从解析语言句子的角度来解决这个问题,而不是试图解析结构化数据或数学格式。
我不推荐使用pyparsing来处理这种语言解析。
玩得开心:
from pyparsing import Regex, oneOf
THE_NAMES = \
"""Joe
bob
Jimmy X
grjiaer-rreaijgr Y
"""
THE_THINGS_THEY_DO = \
"""Joe A
bob B
Jimmy X C
Jimmy X X
grjiaer-rreaijgr Y Y
"""
ACTION = Regex('.*')
NAMES = THE_NAMES.splitlines()
print NAMES
GRAMMAR = oneOf(NAMES) + ACTION
for line in THE_THINGS_THEY_DO.splitlines():
print GRAMMAR.parseString(line)