銀月の符号

Python 使い見習いの日記・雑記

raw ユニコード文字列リテラルの罠

とある Windows のファイルパスらをリテラル表記していたら UnicodeError で怒られるパスがみつかったので数分立ち止まらざるをえなかった。で、発覚したのがこれ。raw ユニコード文字列リテラルでは「バックスラッシュの直後の u, U に注意」。

>>> ur'\u' # バックスラッシュと u の 2 文字になって欲しい…
UnicodeDecodeError: 'rawunicodeescape' codec can't decode bytes in position 0-1:
 truncated \uXXXX

raw ユニコード文字列リテラルではバックスラッシュの後ろに u や U が続くとエスケープ処理が発生する。うぉ? いままで知らなかった。バックスラッシュのエスケープ全無効じゃないのかっ。

"r" および "R" 接頭文字を "u" や "U" と合わせて使った場合、\uXXXXおよび \UXXXXXXXX エスケープシーケンスは処理されますが、 その他のバックスラッシュはすべて文字列中に残されます 。

http://www.python.jp/doc/release/ref/strings.html

そして、これを無効にしようとしてバックスラッシュを2つ重ねると \u, \U エスケープシーケンスは無効になるがバックスラッシュが 2 つとも残る、という仕様になっている。

>>> ur'\\u'
u'\\\\u'

なので

>>> r'\u'.decode()
u'\\u'
>>> unicode(r'\u')
u'\\u'

などで代用することに。もちろん raw 文字列で書くのをあきらめるのもありだと思う。

せっかくなのでもう一つの raw 文字列の罠、「バックスラッシュで終わる文字列を表現できない。」にも触れておきますね。

>>> r'foo\'
  File "<stdin>", line 1
    r'foo\'
          ^
SyntaxError: EOL while scanning single-quoted string

雑談のネタなどにどうぞ。