3

アクセントを含む入力をユーザーに求めるプログラムを書いています。ユーザー入力文字列は、プログラムで宣言された文字列と一致するかどうかを確認するためにテストされます。以下に示すように、私のコードは機能していません。


コード

# -*- coding: utf-8 -*-

testList = ['má']
myInput = raw_input('enter something here: ')

print myInput, repr(myInput)
print testList[0], repr(testList[0])
print myInput in testList

pydevを使用したEclipseでの出力

enter something here: má
m√° 'm\xe2\x88\x9a\xc2\xb0'
má 'm\xc3\xa1'
False

IDLEでの出力

enter something here: má
má u'm\xe1'
má 'm\xc3\xa1'

Warning (from warnings module):
  File "/Users/ryanculkin/Desktop/delete.py", line 8
    print myInput in testList
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
False

2つの文字列を比較するときに、コードでTrueを出力するにはどうすればよいですか?

さらに、同じ入力でこのコードを実行した結果は、EclipseとIDLEのどちらを使用するかによって異なることに注意してください。どうしてこれなの?私の最終的な目標は、私のプログラムをWebに掲載することです。結果が非常に不安定に見えるので、私が知っておく必要があることはありますか?

4

3 に答える 3

9

実行しているraw_inputのはバイト文字列ですが、比較している文字列は Unicode 文字列です。Python 2 はそれらを共通の型に変換して比較しようとしますが、バイト文字列のエンコーディングを推測できないため失敗します。そのため、解決策は明示的に変換を行うことです。

原則として、プログラム内のすべての文字列を Unicode 文字列として保持する必要があります。バイトとして読み取ったものはすべて、すぐに Unicode に変換されます。プログラムでリテラルとして持っているものはすべて、何らかの理由で明示的にバイト文字列にする必要がない限り、Unicode リテラルにします。これによりunicode サンドイッチが生成され、通常は作業が楽になります。

リテラルの場合、文字列を として宣言するか、次のようにしますu'má'

from __future__ import unicode_literals

スクリプトの上部近くで'un-prefixed strings'ユニコードを作成します。発生しているエラーは、このビットを既に実行していることを意味します。

Unicode 文字列を読み取るには、バイト文字列が得られることを認識する必要があります。そのため、そのメソッドraw_inputを使用して変換する必要があります。STDINのエンコーディング.decodeを渡す必要があります-これは次のように利用できます(これがUTF8であると想定しないでください-常にではありませんが、常にそうであるとは限りません)-したがって、行全体は次のようになります。.decodesys.stdin.encoding

string = raw_input(...).decode(sys.stdin.encoding) 

しかし、これを回避する最も簡単な方法は、可能であれば Python 3 にアップグレードすることです。これにより、input()(それ以外の場合は Py2 のように動作しraw_inputます) Unicode 文字列が得られます (.decode必要になるため、覚えておく必要はありません)。接頭辞のない文字列は、デフォルトでは Unicode 文字列です。これにより、アクセント付きの文字を扱う作業がはるかに簡単になります。これは、正しいことを行うため、試していたロジックが Py3 でも機能することを本質的に意味します。

ただし、表示されているエラーは Py3 でもマニフェストされることに注意してください。ただし、デフォルトで正しいことを行うため、エラーが発生するまでは苦労する必要があります。しかし、そうすると、比較は警告なしで False になります。Py3 はバイト文字列と Unicode 文字列の間で暗黙的な変換を試みることはありません。例外をスローします。

于 2012-06-17T04:06:36.350 に答える
0

PyDev は PYTHONIOENCODING を起動構成 > 共通 > エンコーディングのエンコーディングに設定するため、IDLE と PyDev には違いがあることに注意してください。また、そのエンコーディングで sys.setdefaultencoding を実行します (カスタムの sitecustomize.py があります)。

于 2012-06-25T11:47:19.510 に答える
0

1 つのオプションは、次のように文字のアクセントを取り除くことです。他の場所を読んだ# -*- coding: utf-8 -*-後、#!/usr/bin/pythonすべての文字列をユニコードで保持するオプションを設定できることがわかりました。その場合s = raw_input().decode('utf8')、正しいユニコードを取得するために実行する必要があるかもしれません。

于 2012-06-17T03:04:46.047 に答える