1

質問

  1. 最後の 2 つのケースの出力は両方とも unicode ですが、一方のケースでは分数が表示され、もう一方のケースでは分数を表す他のコードが表示されるのはなぜですか?

  2. 分数から小数 (-1.75) に変換する最もクリーンな方法は何ですか?

バックグラウンド

私はいくつか の出力分数を読み取るためにBeautifulSoupandを使用しています。以下は、この問題をテストするために使用している python コードと、結果の出力です。以下のコードでは、PythonHTML.HTML

print type(c[0])
print c[0]
print type(c[0].get_text())
print c[0].get_text()
print type(re.split(" ", c[0].get_text())[0])
print re.split(" ", c[0].get_text())

そしてこれは出力します:

<class 'bs4.element.Tag'>
<b>-1¾ -101</b>
<type 'unicode'>
-1¾ -101
<type 'unicode'>
[u'-1\xbe\xa0-101']
4

1 に答える 1

2

最初に、質問の簡単な部分を整理しましょう。

リストを印刷するreprと、内容の がリスト内の項目を表すために使用されます。だから以来

re.split(" ", c[0].get_text())

がリストの場合、print ステートメントはリスト内の要素の表現を出力します。unicode

In [63]: x = u'-1\xbe\xa0-101'

In [64]: print(x)
-1¾ -101

In [65]: repr(x)
Out[65]: "u'-1\\xbe\\xa0-101'"

ここで興味深いことに、いくつかの Unicode コード ポイントには名前があります。例えば、

In [60]: import unicodedata as ud

In [61]: ud.name(u'\xbe')
Out[61]: 'VULGAR FRACTION THREE QUARTERS'

実際、すべての Unicode 文字を検索して、パターンに一致する名前を持つ文字を見つけることができます'FRACTION (\w+) (\w+)'

import unicodedata as ud
import re

numerator = {
    'ONE':1,
    'TWO':2,
    'THREE':3,
    'FOUR':4,
    'FIVE':5,
    'SIX':6,
    'SEVEN':7,
    'EIGHT':8,
    'NINE':9,
    'ZERO':0,
    }

denominator = {
    'QUARTER':4,
    'HALF':2,
    'SEVENTH':7,
    'NINTH':9,
    'THIRD':3,
    'FIFTH':5,
    'SIXTH':6,
    'EIGHTH':8,
    'SIXTEENTH':16
    }

fraction = {}
for num in range(0x110000):
    s = unichr(num)
    try:
        name = ud.name(s)
    except ValueError:
        continue
    match = re.search('FRACTION ({n}) ({d})'.format(
        n = '|'.join(numerator.keys()),
        d = '|'.join(denominator.keys()),
        ) , name)
    if match:
        fraction[num] = unicode(
           float(numerator[match.group(1)])/denominator[match.group(2)]).lstrip('0')
print(fraction)

これで、Unicode コード ポイントを分数の 10 進数表現にマップするdict名前が付けられました。fractionunicode

{8585: u'.0', 43056: u'.25', 43057: u'.5', 43058: u'.75', 43059: u'.0625', 43060: u'.125', 43061: u'.1875', 188: u'.25', 189: u'.5', 190: u'.75', 8528: u'.142857142857', 8529: u'.111111111111', 8531: u'.333333333333', 8532: u'.666666666667', 8533: u'.2', 8534: u'.4', 8535: u'.6', 8536: u'.8', 8537: u'.166666666667', 8538: u'.833333333333', 8539: u'.125', 8540: u'.375', 8541: u'.625', 8542: u'.875', 69245: u'.333333333333', 3443: u'.25', 3444: u'.5', 3445: u'.75', 69243: u'.5', 69244: u'.25', 11517: u'.5', 69246: u'.666666666667'}

u'-1\xbe\xa0-101'これで、次のように翻訳できます。

text = u'-1\xbe\xa0-101'
print(text.translate(fraction))    

収量

-1.75 -101

したがって、短い答えは次のとおりです。

fraction = {8585: u'.0', 43056: u'.25', 43057: u'.5', 43058: u'.75', 43059: u'.0625', 43060: u'.125', 43061: u'.1875', 188: u'.25', 189: u'.5', 190: u'.75', 8528: u'.142857142857', 8529: u'.111111111111', 8531: u'.333333333333', 8532: u'.666666666667', 8533: u'.2', 8534: u'.4', 8535: u'.6', 8536: u'.8', 8537: u'.166666666667', 8538: u'.833333333333', 8539: u'.125', 8540: u'.375', 8541: u'.625', 8542: u'.875', 69245: u'.333333333333', 3443: u'.25', 3444: u'.5', 3445: u'.75', 69243: u'.5', 69244: u'.25', 11517: u'.5', 69246: u'.666666666667'}
text = c[0].get_text()
text = text.translate(fraction)
parts = map(float, text.split())
print(parts)

収量

[-1.75, -101.0]

将来的には、より多くの分数に Unicode コード ポイントが割り当てられる可能性があることに注意してください。Unicode コード ポイントの名前が、 dict'FRACTION ({n}) ({d})'の生成に使用したパターンと一致しない可能性もあります。fractionそのため、私のソリューションはやや壊れやすく、将来的に更新する必要があるかもしれません.

于 2013-03-03T22:11:13.253 に答える