首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PyParsing OR语句

PyParsing OR语句
EN

Stack Overflow用户
提问于 2011-04-27 11:25:49
回答 2查看 6.1K关注 0票数 5

这将会非常简单,但我尝试匹配两种模式中的一种:

代码语言:javascript
复制
"GET /ligonier-broadcast-media/mp3/rym20110421.mp3 HTTP/1.1"

代码语言:javascript
复制
-

我尝试过这样的东西:

代码语言:javascript
复制
key = Word(alphas + nums + "/" + "-" + "_" + "." + "?" + "=" + "%" + "&")

uri = Or("-" | Group(
                   Suppress("\"") +
                   http_method +
                   key.setResultsName("request_uri") +
                   http_protocol +
                   Suppress("\"")
               )
      )

但看起来并不匹配。我完全不确定如何使用或(),是否应该使用Group(),或者是什么。我知道如果单独调用Group()类中提供的参数就可以工作,但我真的需要破折号或带引号的URI字符串,而不只是一个。

日志格式无法协商,我们正在使用已提供的内容。任何建议都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-27 18:32:15

通常,Or、And、MatchFirst和每个类很少在pyparsing中公开使用。推荐的风格是使用类似的操作符重载。在您的例子中,您同时使用了两种形式,而且这只会妨碍您的工作。

下面是你的表达式,经过一些清理后:

代码语言:javascript
复制
key = Word(alphanums + "/-_.?=%&")
QUOT = Suppress('"')
uri = ("-" | QUOT
             + http_method
             + key("request_uri")
             + http_protocol
             + QUOT
      )

Word的参数是表示允许字符集的字符串。如果只使用一个参数(如本例所示),则字符串将被解释为可作为单词的一部分解析的字符集。如果给定2个字符串,则第一个字符串表示可接受的初始字符集,第二个字符串表示可接受的正文字符集(在定义诸如变量名之类的内容时非常有用,例如,在Python语言中,只允许使用字母和'_‘作为初始字符,但也允许在正文中使用数字。这应该是Word(alphas+'_', alphanums+'_')。因为Word的参数只是字符串,所以不需要单独添加"/" + "-" + "_" + ...,只需将它们组合成一个字符串。

'|‘运算符分隔允许的替换项,从而生成MatchFirst表达式。它之所以被称为MatchFirst,是因为解析器将在第一个给定表达式匹配后停止尝试。因此,如果使用Word(alphas) | Word(nums)解析字符串"abc“,pyparsing甚至不会尝试匹配Word(nums)表达式-第一个替代表达式匹配。如果你想要的东西有一些重叠,这就会变得更加棘手。假设您希望匹配字母单词、字母单词或字母单词和字母单词,并且您希望解析字符串"abc123“。此解析器:

代码语言:javascript
复制
Word(alphas) | Word(nums) | Word(alphanums)

将解析具有前导Word(alphas)的字符串的开头'abc‘。我们通常可以通过重新安排备选方案来解决这样的问题,例如:

代码语言:javascript
复制
Word(alphanums) | Word(alphas) | Word(nums)

但并不是所有的案例都能如此容易地重构。所以pyparsing也支持Or表达式,使用'^‘运算符定义(我之所以选择这个运算符,是因为'^’让我想起了一对绘图员用来测量长度的分隔符)。Or表达式尝试应用所有给定的备选方案,并选择匹配时间最长的方案。因此,您可以将我的小测试示例编写为:

代码语言:javascript
复制
Word(alphas) ^ Word(nums) ^ Word(alphanums)

现在,pyparsing不会在匹配"abc“时停止,而是会尝试所有备选方案,并最终选择第三个备选方案,匹配"abc123",因为它提供了更长的匹配时间。

对于您的URI定义,不需要执行或匹配。解析器不可能将前导'-‘与带引号的HTTP命令字符串混淆。因此,使用MatchFirst就足够了,这是通过使用'|‘运算符完成的。

其他一些项目:

如果可以的话,不要用编写"\""。正因为如此,Python支持两个引号字符。请改用'"'。反斜杠是为C程序员准备的,从pyparsing 1.4.6开始,Windows文件names.

  • expr.setResultsName("name")已被简化为expr("name")。只有当你想在结果中保留一些结构,或者当你有一个重复的结构,其中有一些带有结果名称的内部表达式时,缩短的语法才能真正帮助解析器definitions.
  • Use组的可读性。解析器并不真正需要,只需在结果上添加另一个列表容器包装器,就需要额外的[0]索引来获取解析后的数据。

(如果您确实决定显式调用OrAnd等,请确保传递表达式列表,而不只是将它们作为参数列出给表达式构造函数-请参阅Why is ordered choice in pyparsing failing for my use case?了解这种拼写错误如何使事情变得一团糟,这就是我鼓励使用算术运算符来组合解析器的原因。)

票数 19
EN

Stack Overflow用户

发布于 2011-04-27 11:55:35

我觉得你想..。

代码语言:javascript
复制
from pyparsing import oneOf
# more code here
uri = oneOf(["-", <insert long match expr here>])`
uri.matchString(someStringVar)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5798994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档