问题描述
我目前正在使用 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 中处理?
解决方法
字符串使用 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,4)
Integer part 7,8)
Fraction
实例可以以通常的方式转换为 float
或 str
:
>>> ff = fractions.Fraction(15,8)
>>> ff
Fraction(15,8)
>>> str(ff)
'15/8'
>>> float(ff)
1.875