0

Windows パス区切り文字をエスケープして、この文字列を変更する必要があります。元の文字列を自分で定義していないため、生の文字列「r」を前に保留することはできません。

私はこれを必要とする:

s = 'C:\foo\bar'

これになる:

s = 'C:\\foo\\bar'

ここや他の場所で見つけることができるものはすべて、これを行うように言っています:

s.replace( r'\\', r'\\\\' )

(想像できない生の文字列内の文字をエスケープする必要があるのはなぜですか)

しかし、文字列を印刷すると、これになります。明らかに、変更された文字列のエスケープを再解釈することが決定されました。

C:♀oar

これは、Perl では非常に簡単です。Pythonでこれを解決するにはどうすればよいですか?

4

2 に答える 2

4

一連の質問を行ったり来たりした後、実際の問題は次のとおりです。

次のような内容のファイルがあります。

C:\foo\bar
C:\spam\eggs

そのファイルの内容を読み取り、それをパス名として使用し、エスケープする方法を知りたいとします。

答えは、何もする必要がないということです。

バックスラッシュ シーケンスは、ファイルや(3.x では、2.x では) などから読み取った文字列オブジェクトではなく、文字列リテラルで処理されます。したがって、これらのバックスラッシュ シーケンスをエスケープする必要はありません。inputraw_input

考えてみれば、文字列を文字列に変換するために文字列を引用符で囲む必要はありません。そして、これはまったく同じケースです。引用符とエスケープするバックスラッシュはどちらも、文字列そのものではなく、文字列の表現の一部です。


つまり、サンプル ファイルを として保存しpaths.txt、次のコードを実行するとします。

with open('paths.txt') as f:
    file_paths = [line.strip() for line in f]
literal_paths = [r'C:\foo\bar', r'C:\spam\eggs']
print(file_paths == literal_paths)

… 印刷されTrueます。


もちろん、ファイルが正しく生成されておらず、次のようなゴミでいっぱいの場合:

C:♀oar

次に、「バックスラッシュをエスケープする」方法はありません。バックスラッシュはエスケープするためのものではないからです。そこにあるはずの元のデータを再構築するヒューリスティック コードを作成することもできますが、それが最善の方法です。

たとえば、次のようなことができます。

backslash_map = { '\a': r'\a', '\b': r'\b', '\f': r'\f', 
                  '\n': r'\n', '\r': r'\r', '\t': r'\t', '\v': r'\v' }
def reconstruct_broken_string(s):
    for key, value in backslash_map.items():
        s = s.replace(key, value)
    return s

ただし、16 進数、8 進数、または Unicode エスケープ シーケンスを元に戻す必要がある場合、これは役に立ちません。たとえば、'C:\foo\x02'両方'C:\foo\b'ともまったく同じ文字列を表しているため、その文字列を取得した場合、どちらに変換する必要があるかを知る方法はありません。そのため、できる最善の方法はヒューリスティックです。

于 2013-08-03T01:15:03.757 に答える
0

しないでくださいs.replace(anything)r文字列リテラルの前、開始引用符の前に を貼り付けるだけで、生の文字列が得られます。s実際にはバックスラッシュが含まれていないため、文字列の置換に基づくものはすべて恐ろしいものになります。コードにはバックスラッシュが含まれていますが、実際の文字列ではバックスラッシュにはなりません。

文字列に実際にバックスラッシュが含まれていて、バックスラッシュが 1 つあった場所に 2 つのバックスラッシュを文字列に含める場合は、次のようにします。

s = s.replace('\\', r'\\')

これにより、単一のバックスラッシュが 2 つのバックスラッシュに置き換えられます。ただし、文字列がソース コードで文字通り として表示される場合s = 'C:\foo\bar'、唯一の合理的な解決策はその行を変更することです。それは壊れており、コードの残りの部分に対して何をしても、壊れていないわけではありません。

于 2013-08-03T00:02:50.963 に答える