2

編集:

次のプリントは、私の意図した値を示しています。

(sys.stdout.encoding と sys.stdin.encoding はどちらも「UTF-8」です)。

変数の値が出力値と異なるのはなぜですか? 生の値を変数に入れる必要があります。

>>username = 'Jo\xc3\xa3o'
>>username.decode('utf-8').encode('latin-1')
'Jo\xe3o'
>>print username.decode('utf-8').encode('latin-1')
João

元の質問:

BD のクエリと値の Python へのデコードで問題が発生しています。

DB NLS_LANG を使用して確認しました

select property_value from database_properties where property_name='NLS_CHARACTERSET';

'''AL32UTF8 stores characters beyond U+FFFF as four bytes (exactly as Unicode defines 
UTF-8). Oracle’s “UTF8” stores these characters as a sequence of two UTF-16 surrogate
characters encoded using UTF-8 (or six bytes per character)'''

os.environ["NLS_LANG"] = ".AL32UTF8"

....
conn_data = str('%s/%s@%s') % (db_usr, db_pwd, db_sid)

sql = "select user_name apex.users where user_id = '%s'" % userid

...

cursor.execute(sql)
ldap_username = cursor.fetchone()
...

どこ

print ldap_username
>>'Jo\xc3\xa3o'

私は両方を試しました(同じものを返します)

ldap_username.decode('utf-8')
>>u'Jo\xe3o'
unicode(ldap_username, 'utf-8')
>>u'Jo\xe3o'

どこ

u'João'.encode('utf-8')
>>'Jo\xc3\xa3o'

クエリの結果を適切な 'João' に戻す方法は?

4

1 に答える 1

2

あなたはすでに適切な「João」を持っていると思います。>>> 'Jo\xc3\xa3o'との違い>>> print 'Jo\xc3\xa3o'は、前者はreprオブジェクトを呼び出し、後者はstr(またはおそらくunicode、あなたの場合は) を呼び出すことです。文字列の表現方法です。

いくつかの例は、これをより明確にするかもしれません:

>>> print 'Jo\xc3\xa3o'.decode('utf-8')
João
>>> 'Jo\xc3\xa3o'.decode('utf-8')
u'Jo\xe3o'
>>> print repr('Jo\xc3\xa3o'.decode('utf-8'))
u'Jo\xe3o'

2 番目と 3 番目の結果が同じであることに注目してください。オリジナルldap_usernameは現在 ASCII 文字列です。これは Python プロンプトで確認できます。ACSII オブジェクトを表示している場合は として表示'ASCII string'されますが、Unicode オブジェクトはu'Unicode string'-- キーが先頭のu.

したがって、あなたのldap_username読み取りは'Jo\xc3\xa3o', であり、ASCII 文字列であるため、次が適用されます。

>>> 'Jo\xc3\xa3o'.decode('utf-8')
u'Jo\xe3o'
>>> print 'Jo\xc3\xa3o'.decode('utf-8') # To Unicode...
João
>>> u'João'.encode('utf-8')             # ... back to ASCII
'Jo\xc3\xa3o'

要約すると、文字列のタイプを特定し (type不明な場合に使用)、それに基づいて Unicode にデコードするか、ASCII にエンコードする必要があります。

于 2011-10-24T14:50:45.890 に答える