使用 pyparsing 解析给定范围内的数字

Parsing numbers in a given range with pyparsing

如何使用pyparsing提取给定范围内的数字? 我试过了:

# Number lower than 12:
number = Word(nums).addCondition(lambda tokens: int(tokens[0]) < 12)

test_data = "10 23 11 14 115"
print number.searchString(test_data)

但是 returns:

[['10'], ['3'], ['11'], ['4'], ['5']]

我想要的是:

[['10'], ['11']]

更具体的例子: 我想提取所有看起来像日期一部分的数字并忽略其他数字。 因此,从这个输入:

"""
This is a date: 12 03 2008
This too: 03 12 2008
And this not, values are too large: 123 333 11
"""

我想得到:

[[12, 3, 2008], [3, 12, 2008]]

这里的主要问题是 searchString(和底层 scanString)逐个字符地遍历输入字符串以寻找匹配项。所以在你的输入中(参考位置header):

          1
012345678901234 <- position
10 23 11 14 115

searchString 经过以下步骤:

  • 在位置 0 找到数字“10”,这符合 "less than 12" 条件,所以这是一个匹配项
  • 晋级第2位
  • 跳过空格,前进到位置 3
  • 在位置 3 找到数字“23”,但这不符合条件
  • 前进一位到第3位
  • 找到数字“3”,这符合条件,因此被接受为匹配项
  • 找到数字“11”,这是一个匹配项,前进到位置 8
  • 跳过空格,前进到位置 9
  • 找到数字“14”,这不符合条件
  • 前进一位到第10位
  • 找到数字“4”,这通过了条件,因此接受为匹配项
  • 前进并找到数字“115”,但失败
  • 前进一位,找到数字“15”,失败
  • 前进一位并找到数字“5”,并接受为匹配项

给出您发布的结果,[['10'], ['3'], ['11'], ['4'], ['5']]

一个快速的解决方案是更改 number 的定义以添加 asKeyword=True:

number = Word(nums, asKeyword=True)

As 关键字强制表达式仅在 space-separated 单词的开头匹配。在您的情况下,这将防止意外解析“23”中的“3”和“14”中的“4”等。这将给出您想要的结果 [['10'], ['11']]