如何使用pyparsing解析小数表达式?

2024-03-28 19:03:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我们刚刚开始使用pyparsing并喜欢它到目前为止,但是我们无法让它帮助我们解析小数字符串,将它们转换成数字数据类型。在

例如,如果数据库表中的列值包含字符串:

1 1/2页

我们需要一些方法将其转换为等效的数字python:

1.5条

我们想要一个解析器,它不关心分数中的数字是整数还是实数。例如,我们希望:

1.0 1.0/2.0

…仍然翻译为:

1.5条

实际上,我们希望解析器在概念上执行以下操作:

“1 1/2”=1+0.5=1.5

下面的示例代码似乎让我们更接近。。。在

http://pyparsing.wikispaces.com/file/view/parsePythonValue.py

……但距离不够近,无法取得进展。我们所有生成小数处理程序的测试只返回表达式(1)的第一部分。提示?提示?及时的智慧?:)


Tags: 方法字符串数据库解析器概念示例数字整数
3条回答

不完全是你想要的,但是。。。在

>>> import fractions
>>> txt= "1 1/2"
>>> sum( map( fractions.Fraction, txt.split() ) )
Fraction(3, 2)
>>> float(_)
1.5

此配方可能有帮助:

环顾39号线:

mixed = Combine(numeral + fraction, adjacent=False, joinString=' ')

既然你引用了一些测试,听起来你至少在这个问题上做了些尝试。我假设您已经定义了一个数字,可以是整数或实数-无所谓,您无论如何都要将所有内容转换为float-以及两个数字的分数,可能如下所示:

from pyparsing import Regex, Optional

number = Regex(r"\d+(\.\d*)?").setParseAction(lambda t: float(t[0]))

fraction = number("numerator") + "/" + number("denominator")
fraction.setParseAction(lambda t: t.numerator / t.denominator)

(注意parse操作的使用,它在解析时执行浮点转换和小数除法。我更喜欢在解析时这样做,当我知道某个东西是一个数字或一个分数或其他任何东西时,而不是稍后返回并筛选一堆碎片字符串,尝试重新创建解析器已经完成的识别逻辑。)

以下是我为您的问题编写的测试用例,由整数、分数、整数和分数组成,使用整数和实数:

^{pr2}$

最后一步是如何定义可以是单个数字、分数或单个数字和分数的分数表达式。在

由于pyparsing是从左到右的,它不像regexen那样执行回溯。所以这个表达式不会很好用:

fractExpr = Optional(number) + Optional(fraction)

要将可能来自数字和分数部分的数值相加,请添加以下解析操作:

fractExpr.setParseAction(lambda t: sum(t))

我们的测试打印出来:

1 [1.0]
1.0 [1.0]
1/2 [1.0]
1.0/2.0 [1.0]
1 1/2 [1.5]
1.0 1/2 [1.5]
1.0 1.0/2.0 [1.5]

对于测试用例1/2,它本身只包含一个分数,前导分子与Optional(number)项相匹配,但这只剩下“/2”,它与^{不匹配,幸运的是,由于第二项是可选的,所以它“通过”,但它并不是真正做我们想要的。在

我们需要使fractextpr更聪明一点,让它先查找一个单独的分数,因为在一个单独的数字和一个分数的前导分子之间存在着潜在的混淆。最简单的方法是将fractextpr设为:

fractExpr = fraction | number + Optional(fraction)

现在有了这个变化,我们的测试结果会更好:

1 [1.0]
1.0 [1.0]
1/2 [0.5]
1.0/2.0 [0.5]
1 1/2 [1.5]
1.0 1/2 [1.5]
1.0 1.0/2.0 [1.5]

pyparsing有几个典型的陷阱,这就是其中之一。请记住,pyparsing只执行您告诉它的lookahead,否则它只是直接从左到右的解析。在

相关问题 更多 >