Pythonの生の文字列リテラルが単一のバックスラッシュで終わらないのはなぜですか?

StackOverflow https://stackoverflow.com/questions/647769

質問

技術的には、で説明されているように、奇数個のバックスラッシュドキュメント

>>> r'\'
  File "<stdin>", line 1
    r'\'
       ^
SyntaxError: EOL while scanning string literal
>>> r'\\'
'\\\\'
>>> r'\\\'
  File "<stdin>", line 1
    r'\\\'
         ^
SyntaxError: EOL while scanning string literal

パーサーは生の文字列のバックスラッシュを通常の文字として扱うことができるようですが(生の文字列とは何ですか?)、私はおそらく明らかな何かを見逃しています。 TIA!

役に立ちましたか?

解決

理由は、太字で強調したセクションの一部で説明されています:

  

文字列の引用符は、   バックスラッシュ、、バックスラッシュは残ります   文字列内;たとえば、 r&quot; \&quot;&quot; は   2つで構成される有効な文字列リテラル   文字:バックスラッシュとダブル   見積もり; r&quot; \&quot; は有効な文字列ではありません   リテラル(生の文字列でさえ終わらない   奇数のバックスラッシュで)。   具体的には、生の文字列は終了できません   単一のバックスラッシュ(   バックスラッシュは以下をエスケープします   引用文字)。また、   単一のバックスラッシュとそれに続く改行   これらの2つの文字として解釈されます   行としてではなく、文字列の一部として   継続。

未加工の文字列は100%未加工ではないため、基本的なバックスラッシュ処理がまだ残っています。

他のヒント

Pythonの生の文字列についての全体的な誤解は、ほとんどの人がバックスラッシュ(生の文字列内)は他のすべての文字と同じように普通の文字だと思っているということです。そうではない。理解する鍵は、このpythonのチュートリアルシーケンスです:

  

r 」または「 R 」のプレフィックスが存在する場合、   バックスラッシュは変更せずに文字列に含まれ、すべて   バックスラッシュは文字列に残ります

したがって、バックスラッシュに続く文字は、 生の文字列の一部です。パーサーが生の文字列(Unicode以外の文字列)を入力し、バックスラッシュに遭遇すると、2文字(バックスラッシュとそれに続く文字)があることがわかります。

この方法:

  

r'abc \ d 'は、 a、b、c、\、d

で構成されます      

r'abc \ 'd' は、 a、b、c、\、 '、d

で構成されます      

r'abc \ '' は、 a、b、c、\、 '

で構成されます

and:

  

r'abc \ ' a、b、c、\、' で構成されていますが、現在、終了引用符はありません。

最後のケースは、上記の最後のqouteが文字列ieの一部であるため、ドキュメントによると、現在、パーサーは閉じ引用符を見つけることができないことを示しています。バックスラッシュは文字列を閉じる文字列を「食い尽くす」ため、ここに置くことはできません。

それがそうです! Pythonの小さな欠陥の1つだと思います!

それには十分な理由があるとは思わないが、それは間違いなく構文解析ではない。 \を最後の文字として生の文字列を解析するのは本当に簡単です。

キャッチは、\を生の文字列の最後の文字にすることを許可すると、&quot;を置くことができないことです。生の文字列の中。 Pythonは&quot;最後の文字として\を許可する代わりに。

ただし、これにより問題が発生することはありません。

c:\ mypath \ などのWindowsフォルダーパスを簡単に記述できないことが心配な場合は、 r&quot; Cとして表すことができます。 \ mypath&quot; 、およびサブディレクトリ名を追加する必要がある場合は、文字列の連結を使用しないでください。とにかく正しい方法ではありません。 os.path.join

を使用します
>>> import os
>>> os.path.join(r"C:\mypath", "subfolder")
'C:\\mypath\\subfolder'

もう1つのトリックは、&quot; \&quot;と評価されるときにchr(92)を使用することです。

最近、バックスラッシュの文字列を削除する必要がありましたが、次のようにしてトリックを実行しました:

CleanString = DirtyString.replace(chr(92),'')

これは「理由」を考慮しないことを理解しています。しかし、スレッドは、差し迫った問題の解決策を探している多くの人々を魅了しています。

生の文字列をスラッシュで終了するには、次のトリックを使用することをお勧めします。

>>> print r"c:\test"'\\'
test\

\&quot;生の文字列内で使用できます。その後、文字列リテラルの終わりを識別するために使用することはできません。

最初の&quot;に遭遇したときに文字列リテラルの解析を停止しないのはなぜですか?

その場合、\&quot;文字列リテラル内では許可されません。しかし、そうです。

r '\' が構文的に正しくない理由は、文字列式が未加工であるにもかかわらず、使用される引用符(シングルまたはダブル)が常にエスケープされる必要があるためです。それ以外の場合は引用してください。したがって、単一引用符で囲まれた文字列内で単一引用符を表現する場合、 \ 'を使用する以外に方法はありません。二重引用符についても同様です。

ただし、次のように使用できます:

'\\'

回答を削除した他のユーザー(クレジットを希望するかどうかわからない)は、Python言語のデザイナーが同じ解析ルールを使用してエスケープ文字を生の形式に展開することで、パーサーの設計を簡素化できる可能性があることを示唆しました後付けとして(リテラルがrawとしてマークされている場合)。

それは面白いアイデアだと思い、後世のためのコミュニティwikiとして含めています。

Cからは、単一の\がエスケープ文字として機能し、改行、タブ、引用符などの特殊文字を文字列に挿入できることは明らかです。

実際には、\をエスケープするため、最後の文字として\を許可しません。パーサーをチョークします。しかし、先に指摘したように、\は合法です。

  

その役割にもかかわらず、生の文字列でさえ単一の文字列で終わることはできません   バックスラッシュは次の引用符をエスケープするため   文字-周囲の引用文字をエスケープする必要があります   文字列に埋め込みます。つまり、r&quot; ... \&quot;有効な文字列ではありません   リテラル-生の文字列は奇数個のバックスラッシュで終わることはできません。
  生の文字列を単一のバックスラッシュで終了する必要がある場合は、使用できます   2つ目と2つ目を切り取ります。

いくつかのヒント:

1)パスのバックスラッシュを操作する必要がある場合、標準のPythonモジュールos.pathがあなたの友人です。例:

  

os.path.normpath( 'c:/ folder1 /')

2)バックスラッシュを含む文字列を構築したいが、文字列の最後にバックスラッシュを付けない場合、生の文字列があなたの友達です(リテラル文字列の前に 'r'プレフィックスを使用します)。例:

r'\one \two \three'

3)変数Xの文字列の前にバックスラッシュを付ける必要がある場合、これを行うことができます:

X='dummy'
bs=r'\ ' # don't forget the space after backslash or you will get EOL error
X2=bs[0]+X  # X2 now contains \dummy

4)末尾にバックスラッシュを含む文字列を作成する必要がある場合は、ヒント2と3を組み合わせます:

voice_name='upper'
lilypond_display=r'\DisplayLilyMusic \ ' # don't forget the space at the end
lilypond_statement=lilypond_display[:-1]+voice_name

現在、lilypond_statementには&quot; \ DisplayLilyMusic \ upper&quot;

が含まれています

長いライブpython! :)

n3on

この問題が発生し、場合によっては部分的な解決策が見つかりました。 Pythonは単一のバックスラッシュで文字列を終了できないにもかかわらず、シリアル化して、末尾に単一のバックスラッシュを含むテキストファイルに保存できます。したがって、必要なものがコンピューター上の単一のバックスラッシュでテキストを保存する場合、それは可能です:

x = 'a string\\' 
x
'a string\\' 

# Now save it in a text file and it will appear with a single backslash:

with open("my_file.txt", 'w') as h:
    h.write(x)

ところで、Pythonのjsonライブラリを使用してダンプすると、jsonで動作しません。

最後に、私はSpyderで作業し、変数エクスプローラーで変数をダブルクリックしてスパイダーのテキストエディターで変数を開くと、単一のバックスラッシュが表示され、そのようにクリップボードにコピーできることに気付きました(ほとんどのニーズにはあまり役立ちませんが、多分いくつかのニーズには役立ちます。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top