Python の正規表現で IGNORECASE するときは気をつけよう

Python 3 で文字列が Unicode になりました。というだけで感のいい人は分かるかもしれません。

はい、大文字小文字の判断も ASCII じゃなくて Unicode になります。

In [6]: re.match("[a-z]", 'ı', re.I)
Out[6]: <_sre.SRE_Match object; span=(0, 1), match='ı'>

この文字は LATIN SMALL LETTER DOTLESS I だそうです。

予想外のものにマッチするのは単純にバグになりやすいのもそうですが、この [...] にマッチする部分を作るのも非効率的になります。Python の標準ライブラリの正規表現は最終段階以外が全部 pure Python で書かれているので、正規表現コンパイルが遅く非効率になります。

なお Python の標準ライブラリの正規表現は文字列だけでなくバイト列にも使えて、その場合はこういった罠はありません。

このブログに乗せているコードは引用を除き CC0 1.0 で提供します。