文字列リテラルと '\'

'\n' などの 特殊文字特殊文字と扱いたくないとき、Python では raw string(生文字列)を使う。
文字列の最初の ' または " の直前に r をつければ、スクリプト内の表記通りの文字列として扱われる。

>>> print '[\t]'
[	]
>>> print r'[\t]' #raw string
[\t]

内部的には \ をエスケープしている。

>>> print repr('[\t]')
'[\t]'
>>> print repr(r'[\t]')
'[\\t]'           # \ を重ねて \ 自体をエスケープしてる。

raw string を使わずに同じことをしたければ、明示的に \ を重ねる。

>>> print '[\\t]'
[\t]
>>> print repr('[\\t]')
'[\\t]'

ここまでの理屈は分かりやすい。

エスケープシーケンスと認識できない \ は勝手にエスケープされる。

この場合、r をつけてもつけなくても同じことになる。

>>> print '\z', r'\z'
\z \z
>>> print repr('\z'), repr(r'\z')
'\\z' '\\z'

ちょっと直感に反する気がするけど、仕様だからそういうものだと思うしかない。
ちなみにこのケースは言語によって扱いが違う。
PerlRubyの場合、エスケープと認識できない \ は削除される。

#[Ruby]
irb(main):001:0> puts "\z"
z
=> nil

なお、Perl, Ruby ではシングルクォートで文字列を記述すると、raw string 扱いとなり、Python のraw stringと同じ挙動になる。
C/C++Javaでは raw string という概念が無いので、"\z" などはコンパイルエラーになる。

文字列終端の \ は raw string に出来ない

これもまた特殊ケースとなる。

# \ 直後の ' がエスケープされてしまい文字列が終わっていないことになる。
>>> print 'abc\'

↑ は当然だけど、↓ はかなり戸惑った。

>>> print r'abc\'
SyntaxError: EOL while scanning single-quoted string

文字列末尾でも raw string では \ をエスケープしていいと思うんだけどダメらしい。何か理由があるのかな。
これに関しては PerlRuby も同じ。

raw string に頼らず、明示的に \ を重ねれば期待通りにできる。

>>> print 'abc\\', repr('abc\\')
abc\ 'abc\\'

replaceの \ 地獄

最後の仕様のせいで、\ の replace などは見にくくなってしまう。

hoge_string.replace('\\', '\\\\')

どうしても許せなければ、↓こうでもするしかない。

bslash = '\\'
hoge_string.replace(bslash, bslash * 2)

せめて string モジュールに back_slash定数が欲しかったな。

追記

C++0xでは raw string があるみたい。http://d.hatena.ne.jp/faith_and_brave/20071102/1194012296