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

时间:2016-10-02 15:36:03

标签: python 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)

但它返回:

[['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]]

1 个答案:

答案 0 :(得分:0)

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

          1
012345678901234 <- position
10 23 11 14 115

searchString执行以下步骤:

  • 找到数字&#34; 10&#34;在位置0,这匹配&#34;小于12&#34;条件,所以这是匹配
  • 前进至位置2
  • 跳过空白,前进到位置3
  • 找到数字&#34; 23&#34;在位置3,但这不符合条件
  • 将一个地方推进到位置3
  • 找到数字&#34; 3&#34;,这符合条件,因此被接受为匹配
  • 找到号码&#34; 11&#34;,这是匹配,前进到位置8
  • 跳过空白,前进到位置9
  • 找到数字&#34; 14&#34;,这不符合条件
  • 将一个地方推进到位置10
  • 找到数字&#34; 4&#34;,这会传递条件,因此被接受为匹配
  • 前进并查找号码&#34; 115&#34;,然后失败
  • 前进一个地方,找到号码&#34; 15&#34;,然后失败
  • 前进一个地方,找到号码&#34; 5&#34;,并接受为匹配

根据您发布的结果[['10'], ['3'], ['11'], ['4'], ['5']]提供结果。

快速解决方案是将number的定义更改为添加asKeyword=True

number = Word(nums, asKeyword=True)

as关键字强制表达式仅在空格分隔的单词的开头处匹配。在您的情况下,这将防止意外解析&#39; 3&#39;在&#39; 23&#39;和&#39; 4&#39;在&#39; 14&#39;等。这将得到您想要的结果[['10'], ['11']]