首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >parseString工作了,scanString失败了?

parseString工作了,scanString失败了?
EN

Stack Overflow用户
提问于 2012-10-17 13:40:37
回答 1查看 377关注 0票数 3

在parseString给出正确结果的情况下,让scanString工作有问题。

此序列起作用:

代码语言:javascript
复制
alpha_rev = pyp.Word(pyp.alphas, max=2)
num_rev = pyp.Word('123456789', max=2)
space = pyp.White(ws=" ").suppress()

revisionExpr = (
    pyp.StringStart().leaveWhitespace() +
    space +
    pyp.Combine(alpha_rev + 
    pyp.Optional(num_rev)("rev"))
    )

rev_string = ' K        WI, This is the title'

for match_str, start, end in (
    revisionExpr.scanString(rev_string, maxMatches=1)):
    print match_str

['K']

有时会有一个“牧师”或“牧师”在修订之前;这将失败:

代码语言:javascript
复制
revisionExpr = (
    pyp.StringStart().leaveWhitespace() +
    space +
    pyp.Combine(alpha_rev + 
    pyp.Optional(num_rev)("rev"))
    |
    pyp.CaselessLiteral("Rev") + pyp.Optional('.') + 
    pyp.Combine(alpha_rev + 
    pyp.Optional(num_rev)("rev"))
    )

for match_str, start, end in (
    revisionExpr.scanString(rev_string, maxMatches=1)):
    print match_str

print match_str
NameError: name 'match_str' is not defined

为什么"|“会导致匹配失败?请注意,这适用于第一个和第二个示例:

代码语言:javascript
复制
revisionTokens = revisionExpr.parseString(rev_string)

如果我将上一个示例的第二部分(在“|”之后)提取到类似第一个示例的形式中,如果我添加"Rev.“,它就可以工作。在rev_string中的"K“前面。不幸的是,第一个表达式中的前导空格是唯一标识修订字符串所必需的,否则,在本例中,"WI“将匹配。

我尝试使用scanString而不是parseString,因为它返回比赛的开始和结束位置,这有助于后面的一些处理。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-07 13:19:20

问题是,您的"or“运算符("|")只查看它左边和右边的元素。您没有正确地对语法元素进行分组。下面是你的语法再细分一下:

代码语言:javascript
复制
left_expr = pyp.Combine(alpha_rev + pyp.Optional(num_rev)("rev")
right_expr = pyp.CaselessLiteral("Rev")

joined_expr = left_expr | right_expr

final_expr = (pyp.StringStart().leaveWhitespace() +
    space +
    joined_expr +
    pyp.Optional('.') +
    pyp.Combine(alpha_rev +
      pyp.Optional(num_rev)("rev"))
    )

正如您所看到的,这并不完全是您想要的-它将查找文本"Rev“或实际修订版,然后是另一个修订版。表达式的固定版本如下:

代码语言:javascript
复制
revisionExpr = (
    pyp.StringStart().leaveWhitespace() +
    space +
    (
        pyp.Combine(alpha_rev +
            pyp.Optional(num_rev)("rev")
        )
        |
        (
            pyp.CaselessLiteral("Rev") + 
            pyp.Optional('.') +
            pyp.Combine(alpha_rev +
                pyp.Optional(num_rev)("rev"))
        )
    )
)

但是,你可以让你的语法更简洁一些:

代码语言:javascript
复制
revisionExpr = (
    pyp.StringStart().leaveWhitespace() +
    space +
    pyp.Suppress(
        pyp.Optional(
            pyp.CaselessLiteral("Rev") + 
            pyp.Optional('.')
        )
    ) +
    pyp.Combine(
        alpha_rev +
        pyp.Optional(num_rev)("rev")
    )
)

在此版本中,您只需标记"Rev.“文本是可选的,放在预期的位置,而不是让解析器选择只解析修订版或"Rev.“+修订版。这完全避免了使用"|“运算符产生的任何问题。

不要忘记,PyParsing使用运算符重载来提供更好的语法,如果语法造成混乱(就像在这个场景中),您可能会更好地使用像"pyp.Or(a,b)“这样的长格式方法调用。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12927787

复制
相关文章

相似问题

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