一連の質問を行ったり来たりした後、実際の問題は次のとおりです。
次のような内容のファイルがあります。
C:\foo\bar
C:\spam\eggs
そのファイルの内容を読み取り、それをパス名として使用し、エスケープする方法を知りたいとします。
答えは、何もする必要がないということです。
バックスラッシュ シーケンスは、ファイルや(3.x では、2.x では) などから読み取った文字列オブジェクトではなく、文字列リテラルで処理されます。したがって、これらのバックスラッシュ シーケンスをエスケープする必要はありません。input
raw_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'
ともまったく同じ文字列を表しているため、その文字列を取得した場合、どちらに変換する必要があるかを知る方法はありません。そのため、できる最善の方法はヒューリスティックです。