【问题标题】:Tokenizing Rule Precedence Pyparsing标记规则优先级 Pyparsing
【发布时间】:2014-03-09 22:30:05
【问题描述】:

下面是我的玩具解析器:

from pyparsing import Word,OneOrMore,alphanums,nums

number=Word(nums)
word=OneOrMore(Word(alphanums))
greeting = word+(number)

tests = "Hello3 World 1234"
print tests, "->", greeting.parseString(tests)

我期望得到的结果是

['Hello3','World','1234']

但我得到了错误:

ParseException: Expected W:(0123...) (at char 17), (line:1, col:18)

'1234'字符串不应该先被'number'规则匹配,然后被'word'规则忽略吗?

我怀疑现在是深夜,我错过了文档中一些非常基本的东西,但我已经浏览了 'pyparsing 入门' O'Reilly pdf 两次,但找不到解决方案。 感谢您的帮助。

【问题讨论】:

  • 否 - '1234' 字符串将与 OneOrMore 类中内置的重复匹配,您已将其定义为接受一个或多个由字母数字字符组成的单词,与 '1234' 匹配。如果想让 word 不接受数字,则将 word 重新定义为OneOrMore(~number+Word(alphanums)),这样由所有数字组成的词都将包含在 word 部分中,以便后面的数字部分有匹配的机会。

标签: python tokenize pyparsing rule operator-precedence


【解决方案1】:

这是将您的“1234”与word 规则相匹配,因为您说它可以是字母或数字。 word 规则不断捕获包括“1234”在内的术语,因此错误是永远不会命中 number 规则。

如果您对word 的规则更接近python 对标识符的定义(不能以数字开头),这将修复您的解析器:

from pyparsing import Word, OneOrMore, alphas, alphanums, nums

number=Word(nums)
word=OneOrMore(Word(initChars=alphas, bodyChars=alphanums))
greeting = word+(number)

tests = "Hello3 World 1234"
print tests, "->", greeting.parseString(tests)

【讨论】:

  • 谢谢,您的解决方案解决了。但更一般地说,为什么首先应用“word”规则而不是“num”?是因为规则是从左到右应用的,更具体等吗?有没有办法让我按顺序应用规则,而不必更改“单词”规则?在我的最终应用程序中,我希望将姓名、电话号码和出生日期标记化,然后应用语法将属于同一个人的那些内容拼接在一起。我错过了重点吗?
  • 是的,OneOrMore 是贪婪的,会在应用number 规则之前消耗所有令牌。您需要在 word 之前使用 MatchFirstnumber 以提供优先权。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多