如何将 Vulgar 分数转换为浮点数?

Posted

技术标签:

【中文标题】如何将 Vulgar 分数转换为浮点数?【英文标题】:How to convert Vulgar Fractions to floats? 【发布时间】:2021-08-17 11:30:32 【问题描述】:

我目前正在使用 Gmail API 抓取 Gmail 数据。我正在抓取的一些电子邮件包含粗俗的部分,如下所示:

8⅜
6⅞
7¾
7⅞

使用 Gmail API 的上述粗俗分数的 html 输出如下所示:

8=E2=85=9C
6=E2=85=9E
7=C2=BE
7=E2=85=9E

如何将这些转换回字符串,例如'8 3/8',以便在 Python 中进行处理?

【问题讨论】:

你想要的输出是什么? @CrazyChucky 某种形式的字符串,例如“8 3/8”或单独的“8”和“3/8” 【参考方案1】:

字符串使用quoted printable 编码进行编码,这是一种将非ASCII 字节编码为ASCII 的方法。您可以像这样解码为str

import quopri

s = '8=E2=85=9C'
f = quopri.decodestring(s).decode('utf-8')
print(f)

打印

8⅜

str(8)加上unicode字符VULGAR FRACTION THREE EIGHTHS组成。

我们可以使用 unicode normalisation 进一步分解字符串

import unicodedata as ud

decomposed = ud.normalize('NFKD', f)
print(decomposed)

输出

83⁄8

我们可以结合这些方法来获取每个字符串的所有部分并将它们转换为整数或fractions:

import fractions
import quopri
import unicodedata as ud


values = """\
8=E2=85=9C
6=E2=85=9E
7=C2=BE
7=E2=85=9E
"""

for value in values.splitlines():
    string_ = quopri.decodestring(value).decode('utf-8')
    # Assume each string is composed solely of one or more digits,
    # with the fraction character at the end
    int_part = int(string_[:-1])

    normalised = ud.normalize('NFKD', string_[-1])
    # Note that the separator character here is chr(8260),
    # the 'FRACTION SLASH' character, not the ASCII 'SOLIDUS'
    nominator, _, denominator = normalised.partition('⁄')

    fractional_part = fractions.Fraction(*map(int, (nominator, denominator)))

    print(f'Integer part int_part, fractional part fractional_part!r')
print()

结果:

Integer part 8, fractional part Fraction(3, 8)
Integer part 6, fractional part Fraction(7, 8)
Integer part 7, fractional part Fraction(3, 4)
Integer part 7, fractional part Fraction(7, 8)

Fraction 实例可以按通常的方式转换为floatstr

>>> ff = fractions.Fraction(15, 8)
>>> ff
Fraction(15, 8)
>>> str(ff)
'15/8'
>>> float(ff)
1.875

【讨论】:

这是一个值得了解的好模块!我不确定提问者是否特别需要'3/8' 而不是'⅜',但你知道是否有办法执行这种转换(除了编写自己的查找表之外)?遗憾的是Fraction() 无法识别其字符串输入格式中的粗俗分数字符。 @CrazyChucky 我本来想说不,但事实证明,粗俗分数 unicode 字符可以规范化为 ASCII 数字,所以这是可能的。我已经编辑了答案来演示。 太棒了!希望我能给予第二次投票。为了清楚起见,我唯一建议的是将手动索引的部分替换为*int_part, fraction_char = string_ 好吧,你仍然需要用int_part = int(int_part) 将其更改为整数,但* 使得expand 可以获取除单独命名的fraction_char 之外的所有字符。 @CrazyChucky 对不起,我错过了*。这行得通,但如果有多个数字,int_part 将被拆分为一个列表,因此必须在转换为 int 之前加入它。我认为这可能是索引比解包更好的少数场合之一。

以上是关于如何将 Vulgar 分数转换为浮点数?的主要内容,如果未能解决你的问题,请参考以下文章

如何将表示为字符串的数字转换为浮点数

如何将带指数的字符串转换为浮点数?

如何在python中将23位浮点数从字符串转换为浮点数并返回?

如何将 NSString 值 @"3.45" 转换为浮点数?

如何将字符串转换为浮点数?

OCaml如何将多态数转换为浮点数?