我正在解析一个包含分数Unicode表示的网页。 我希望能够直接将这些字符串转换为浮点数。 例如:
"⅕" 将变成 0.2
有什么建议可以在Python中完成这个任务吗?
我正在解析一个包含分数Unicode表示的网页。 我希望能够直接将这些字符串转换为浮点数。 例如:
"⅕" 将变成 0.2
有什么建议可以在Python中完成这个任务吗?
您想使用unicodedata模块:
import unicodedata
unicodedata.numeric(u'⅕')
这将打印:
0.20000000000000001
如果字符没有数值,那么unicodedata.numeric(unichr[, default])
将返回默认值,如果未提供默认值,则会引发ValueError异常。numeric(char)
在处理3¾
这样的内容时无法正常工作。这需要更多的努力:from unicodedata import numeric
samples = ["3¼","19¼","3 ¼","10"]
for i in samples:
if len(i) == 1:
v = numeric(i)
elif i[-1].isdigit():
# normal number, ending in [0-9]
v = float(i)
else:
# Assume the last character is a vulgar fraction
v = float(i[:-1]) + numeric(i[-1])
print(i, v)
输出:
3¼ 3.25
19¼ 19.25
3 ¼ 3.25
10 10.0
/[\u2150-\u215E\u00BC-\u00BE]/g
由于Unicode中只定义了有限数量的分数,因此使用字典似乎是合适的:
Fractions = {
u'¼': 0.25,
u'½': 0.5,
u'¾': 0.75,
u'⅕': 0.2,
# add any other fractions here
}
更新:使用unicodedata
模块是更好的解决方案。
>>> import unicodedata
>>> unicodedata.lookup('VULGAR FRACTION ONE QUARTER')
u'\xbc'
>>> unicodedata.decomposition(unicodedata.lookup('VULGAR FRACTION ONE QUARTER'))
'<fraction> 0031 2044 0034'
更新:我会将这个答案保留在这里供参考,但是根据Karl的回答,使用unicodedata.numeric()是一个更好的选择。
import unicodedata
# Assuming that the unicode is always the last character. You always going to see stuff like "3¼", or "19¼" whereas stuff like "3¼5"
# does not have a clear interpretation
def convertVulgarFractions(vulgarFraction):
if (len(vulgarFraction) == 1):
return unicodedata.numeric(vulgarFraction)
if (len(vulgarFraction) > 1) & (not (vulgarFraction[:len(vulgarFraction)-1].isdigit())):
raise ArithmeticError("The format needs to be numbers ending with a vulgar fraction. The number inserted was " +
str(vulgarFraction))
if vulgarFraction[len(vulgarFraction)-1].isdigit():
return float(vulgarFraction)
else:
return float(vulgarFraction[:len(vulgarFraction)-1]) + unicodedata.numeric(vulgarFraction[len(vulgarFraction)-1])
虽然不完全符合要求,但也许有人想将其转换为分数而不是浮点数。毕竟,它真正代表的是一个分数。
unicodedata.normalize("NFKC", "⅕")
的结果是 "1⁄5"
。这目前还不能被 fractions.Fraction
理解,因为它期望用 /
而不是 ⁄
描述分数。不过,这很容易替换:
In [313]: def unifrac_to_frac(s):
...: return fractions.Fraction(unicodedata.normalize("NFKC", s).replace("⁄", "/"))
...:
In [315]: unifrac_to_frac("⅕")
Out[315]: Fraction(1, 5)
In [316]: unifrac_to_frac("½")
Out[316]: Fraction(1, 2)
In [317]: unifrac_to_frac("↉")
Out[317]: Fraction(0, 1)
>>> unicodedata.numeric('⅕')
0.2