3

私はPython上でPHPと同様に動作するhtmlエンティティエンコーダー/デコーダーを作成しようとしていhtmlentitiesますhtml_entity_decode。これは通常、スタンドアロンスクリプトとして機能します。

私の入力:

Lorem ÁÉÍÓÚÇÃOÁáéíóúção @#$%*()[]<>+ 0123456789

python decode.py

出力:

Lorem ÁÉÍÓÚÇÃOÁáéíóúção @#$%*()[]<>+ 0123456789

Autokeyスクリプトとして実行すると、次のエラーが発生します。

Script name: 'html_entity_decode'
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/autokey/service.py", line 454, in execute
    exec script.code in scope
  File "<string>", line 40, in <module>
  File "/usr/local/lib/python2.7/dist-packages/autokey/scripting.py", line 42, in send_keys
    self.mediator.send_string(keyString.decode("utf-8"))
  File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-12: ordinal not in range(128)

私は何が間違っているのですか?スクリプトは次のとおりです。

import htmlentitydefs
import re

entity_re = re.compile(r'&(%s|#(\d{1,5}|[xX]([\da-fA-F]{1,4})));' % '|'.join(
    htmlentitydefs.name2codepoint.keys()))

def html_entity_decode(s, encoding='utf-8'):

    if not isinstance(s, basestring):
        raise TypeError('argument 1: expected string, %s found' \
                        % s.__class__.__name__)

    def entity_2_unichr(matchobj):
        g1, g2, g3 = matchobj.groups()
        if g3 is not None:
            codepoint = int(g3, 16)
        elif g2 is not None:
            codepoint = int(g2)
        else:
            codepoint = htmlentitydefs.name2codepoint[g1]
        return unichr(codepoint)

    if isinstance(s, unicode):
        entity_2_chr = entity_2_unichr
    else:
        entity_2_chr = lambda o: entity_2_unichr(o).encode(encoding,
                                                           'xmlcharrefreplace')
    def silent_entity_replace(matchobj):
        try:
            return entity_2_chr(matchobj)
        except ValueError:
            return matchobj.group(0)

    return entity_re.sub(silent_entity_replace, s)

text = clipboard.get_selection()
text = html_entity_decode(text)
keyboard.send_keys("%s" % text)

私はそれを要点https://gist.github.com/607454で見つけました、私は著者ではありません。

4

2 に答える 2

3

バックトレースを見ると、おそらく問題は、UTF-8 でエンコードされたバイト文字列を想定している keyboard.send_keys に Unicode 文字列を渡していることです。autokey は文字列をデコードしようとしますが、入力が utf-8 ではなくユニコードであるため失敗します。これは autokey のバグのようです: 本当に単純な (バイト) 文字列でない限り、文字列をデコードしようとするべきではありません。

この推測が正しければ、send_keys に unicode インスタンスを渡すようにすることで、これを回避できるはずです。次のようなことを試してください:

text = clipboard.get_selection()
if isinstance(text, unicode):
    text = text.encode('utf-8')
text = html_entity_decode(text)
assert isinstance(text, str)
keyboard.send_keys(text)

アサートは必要ありませんが、html_entity_decode が正しいことを確認するための便利なサニティ チェックです。

于 2013-01-13T21:15:27.347 に答える
2

問題は次の出力です。

clipboard.get_selection()

ユニコード文字列です。

問題を解決するには、次のように置き換えます。

text = clipboard.get_selection()

に:

text = clipboard.get_selection().encode("utf8")
于 2013-01-13T21:31:55.117 に答える