webdevqa.jp.net

"u"と "r"の文字列フラグは正確に何をしますか、そして生の文字列リテラルとは何ですか?

この質問 を尋ねているうちに、生の文字列についてあまり知らなかったことに気づきました。 Djangoのトレーナーであると主張している誰かにとって、これは大したことではありません。

私はエンコーディングが何であるかを知っています、そして私は私がUnicodeであるものを手に入れたのでu''だけが何をするのか知っています。

  • しかし、r''は正確に何をしますか?どのような文字列になりますか?

  • そして何よりも、ur''は一体何をしているのでしょうか。

  • 最後に、Unicode文字列から単純な生の文字列に戻るための信頼できる方法はありますか?

  • ああ、そしてところで、あなたのシステムとあなたのテキストエディタの文字セットがUTF-8に設定されているなら、u''は実際に何かをしますか?

530
e-satis

"raw string "は実際にはありません。生の 文字列リテラル があります。これは、開始引用符の前に'r'でマークされた文字列リテラルです。

「生の文字列リテラル」は、文字列リテラルとは少し異なる構文です。バックスラッシュ\は、「単なるバックスラッシュ」を意味すると解釈されます(そうでなければリテラルを終了させる引用符の直前に来る場合を除く)。改行、タブ、バックスペース、フォームフィードなどを表す「エスケープシーケンス」はありません。通常の文字列リテラルでは、エスケープシーケンスの始まりと見なされないように、各バックスラッシュを2倍にする必要があります。

この構文の変種は、主に正規表現パターンの構文がバックスラッシュで重いためです(しかし、最後にはないので、上記の "except"節は関係ありません)。 - それで全部です。ネイティブのWindowsファイルパス(他のプラットフォームのように通常のスラッシュの代わりにバックスラッシュを使う)を表現することも一般的になりましたが、それはほとんど必要ありません(通常のスラッシュはWindowsでも大丈夫です)。上記)。

r'...'はバイト文字列(Python 2. *では)、ur'...'はUnicode文字列(Python 2. *でも同様)であり、他の3種類の引用符付けもすべてまったく同じタイプの文字列を生成します(たとえばr'...') 、r'''...'''r"..."r"""..."""はすべてバイト文字列などです。

"going back "の意味がよくわからない - 生の文字列 type がないため、本質的な前後方向はありません。これは、完全に通常の文字列オブジェクトを表す代替構文です。またはユニコードです。

そしてもちろん、Python 2 *では、u'...''...'とは常に異なる - 前者はUnicode文字列、後者はUnicode文字列です。リテラルをどのようにエンコードするかは、完全に直交する問題です。

たとえば、(Python 2.6)を検討してください。

>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34

Unicodeオブジェクトは、もちろんより多くのメモリスペースを取ります(非常に短い文字列では非常に小さな違い、明らかに;-)。

587
Alex Martelli

Pythonには2つのタイプの文字列があります:伝統的なstr型と新しいunicode型です。前にuを付けずに文字列リテラルを入力すると、8ビット文字を格納する古いstr型が得られ、前にuを指定すると、Unicode文字を格納できる新しいunicode型が得られます。

rは型をまったく変更しません。文字列リテラルの解釈方法を変更するだけです。 rがないと、バックスラッシュはエスケープ文字として扱われます。 rでは、バックスラッシュはリテラルとして扱われます。どちらの方法でも、タイプは同じです。

urはもちろんバックスラッシュがリテラルバックスラッシュであるUnicode文字列で、エスケープコードの一部ではありません。

str()関数を使用してUnicode文字列を古い文字列に変換しようとすることはできますが、古い文字列で表現できないUnicode文字があると、例外が発生します。あなたが望むなら、あなたは最初に疑問符でそれらを取り替えることができます、しかしもちろんこれはそれらの文字を判読不能にするでしょう。 Unicode文字を正しく処理したい場合はstr型を使用することはお勧めできません。

156
Mark Byers

'raw string' は、表示されているとおりに保存されることを意味します。たとえば、'\'は、 エスケープ ではなく、 バックスラッシュ です。

47
xiaolong

接頭辞 "u"は、値がunicodeではなくstr型であることを示します。

生の文字列リテラルは "r"を前に付けてエスケープシーケンスをエスケープするので、len(r"\n")は2です。エスケープシーケンスをエスケープシーケンスで終わらせることはできません。有効なエスケープシーケンスではありません(例:r"\") 。

"Raw"は型の一部ではありません。値を表現するための1つの方法にすぎません。たとえば、"\\n"r"\n"は、320x20、および0b100000が同一であるのと同じように、同一の値です。

Unicodeの生の文字列リテラルを持つことができます。

>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2

ソースファイルのエンコーディングはソースファイルの解釈方法を決定するだけで、それ以外の表現や型には影響しません。ただし、ASCII以外のエンコーディングで意味が変わるようなコードを避けるために、 推奨 を使用してください。

ASCII(またはPython 3.0の場合はUTF-8)を使用するファイルはコーディングクッキーを持つべきではありません。 Latin-1(またはUTF-8)は、コメントまたはdocstringがLatin-1を必要とする著者名を言及する必要がある場合にのみ使用されるべきです。それ以外の場合は、文字列リテラルに非ASCIIデータを含めるには、\ x、\ u、または\ Uエスケープを使用することをお勧めします。

32
Roger Pate

簡単に説明しましょう。Python2では、文字列を2つの異なるタイプで格納できます。

最初のものはpythonではstr typeであるASCIIで、1バイトのメモリを使用します。 (256文字、主に英語のアルファベットと簡単な記号を格納します)

2番目の型はUNICODEで、これはpythonではunicode typeで、2バイトのメモリを使用します。 (65536文字なので、これには地球上のすべての言語のすべての文字が含まれます)

デフォルトでは、pythonはstr typeを好みますが、文字列をunicode typeに格納したい場合はuu)のようにテキストの前に置くことができます。 'text'またはunicode( 'text')を呼び出すことでこれを行うことができます。

そのため、uは、strunicodeにキャストする関数を呼び出す簡単な方法です。それでおしまい!

rの部分は、テキストの前に置いて、テキストが生のテキストであることをコンピュータに伝えます。バックスラッシュはエスケープ文字ではいけません。 r '\ n'は改行文字を作成しません。それはただ2文字を含むプレーンテキストです。

strunicodeに変換し、そこに生のテキストを入れる場合は、ruがエラーを起こすのでurを使用してください。

今、重要な部分:

rを使用してバックスラッシュを1つ格納することはできません。これが唯一の例外です。そのため、このコードではエラーが発生します。r '\'

バックスラッシュ(1つだけ)を保存するには、'\\'を使用する必要があります。

複数の文字を保存したい場合は、r '\\'のようにrを使用しても構いません。

rが1つのバックスラッシュ記憶域で動作しない理由はわかりませんが、その理由はまだ誰にも説明されていません。それがバグであることを願っています。

25
off99555

たぶん、これは明白ですが、多分そうではありませんが、 x = chr(92) を呼び出すことで '\' という文字列を作成できます。

x=chr(92)
print type(x), len(x) # <type 'str'> 1
y='\\'
print type(y), len(y) # <type 'str'> 1
x==y   # True
x is y # False
4
Bomba Ps

Unicode文字列リテラル

Unicode文字列リテラル(uで始まる文字列リテラル)は 使用されなくなりました in Python 3.それでも有効ですが、 互換性のためだけ = Pythonで2。

生の文字列リテラル

英語の文字や数字など、簡単に入力できる文字のみで構成される文字列リテラルを作成する場合は、'hello world'と入力するだけです。しかし、よりエキゾチックなキャラクターも含める場合は、回避策を使用する必要があります。回避策の1つは、 エスケープシーケンス です。この方法では、たとえば、文字列リテラルに簡単に入力できる2つの文字\nを追加するだけで、文字列の新しい行を表すことができます。したがって、'hello\nworld'文字列を印刷すると、単語は別々の行に印刷されます。それはとても便利です!

一方、エスケープシーケンスを含む文字列リテラルを作成したいが、Pythonで解釈されたくない場合があります。それらをrawにしたい。これらの例を見てください:

'New updates are ready in c:\windows\updates\new'
'In this lesson we will learn what the \n escape sequence does.'

このような状況では、次のように文字列リテラルの前にr文字を付加するだけで済みます。r'hello\nworld'で、エスケープシーケンスはPythonによって解釈されません。文字列は、作成したとおりに印刷されます。

生の文字列リテラルは完全に「生」ではありませんか?

多くの人は、「引用符で囲まれたものはすべてPythonによって無視される」という意味で、生の文字列リテラルが生であることを期待しています。それは真実ではありません。 Pythonはまだすべてのエスケープシーケンスを認識しますが、それらを解釈するだけではなく、代わりに変更しません。つまり、raw文字列リテラルは、依然として有効な文字列リテラルでなければなりません

文字列リテラルの 字句定義 から:

string     ::=  "'" stringitem* "'"
stringitem ::=  stringchar | escapeseq
stringchar ::=  <any source character except "\" or newline or the quote>
escapeseq  ::=  "\" <any source character>

裸の引用文字'hello'world'またはバックスラッシュ'hello world\'で終わる文字列リテラル(未加工または未加工)が無効であることは明らかです。

1
Jeyekomon