将单词定义为连续的字符块



我正在尝试从以下示例行中提取 id 和数据。我将 id 定义为具有 alphanums 和一些其他字符但不包括逗号的东西。我希望 pyparsing 不会将数据的数字 1 作为 id 的一部分,因为数据是包含逗号和逗号的连续块,并且从 id 中排除了逗号。pyparse 是否应该拒绝整个数据部分作为 id,因为该连续数据块包含 id 部分中未定义的其他字符?我的期望是,规则适用于整个单词,而不是单词片段

joinTokensViaSpace = lambda tokens: " ".join(" ".join(t.split()) for t in tokens)
parser= OneOrMore(Word(alphanums+'-/.'))('id').setParseAction(joinTokensViaSpace) + Word(nums+',.()')('data') 
parser.parseString('                    XXX Y/123          1,234.567890')

我得到的输出

(['XXX Y/1231', ',234.567890'], {'data': [(',

234.567890', 1(], 'id': [('XXX Y/1231', 0(]}(

我期望的输出(['XXX

Y/123', '1,234.567890'], {'data': [('1,234.567890', 1(], 'id': [('XXX Y/123', 0(]}(

一般来说,Word通常会在空格上解析,但不能保证你发现的那样。我尝试稍微更改您的解析器以添加Word的可选asKeyword=True参数,并使用带有周围b标记的Regex,但在这两种情况下,1,234.567890中的","满足正常的断字行为。

最简单的解决方案是在OneOrMore中插入一个负前瞻,然后再匹配Word(alphanums+'-/.')

number = Word(nums+',.()')
parser= OneOrMore(~number + Word(alphanums+'-/.'))('id')
            .setParseAction(joinTokensViaSpace) + number('data')

这样,在开始另一个Word之前,解析器首先检查它是否处于潜在的number,并且只有在没有时才会继续。通过此更改,解析的输出将符合您的预期。(也许我应该像OneOrMore(Word(alphanums+'-/.'), stopOn=number)一样,在OneOrMoreZeroOrMore中添加一个stopOn参数 - 这对于pyparseing开发人员来说确实是一个非常常见的陷阱。

我还看到您正在使用结果名称 - 这是一个好习惯。既然你有它们,我建议你使用dump()作为检查parseString返回的ParseResults结构的最佳工具。

result = parser.parseString('                    XXX Y/123          1,234.567890')
print result.dump()

指纹

['XXX Y/123', '1,234.567890']
- data: 1,234.567890
- id: XXX Y/123

最新更新