始めに
正規表現には\w
というメタ表現があります。私のプロジェクトではフロントのTypeScript, バックエンドにRuby, Pythonを使用しておりました。
もともとは正規表現を使用しないチェックロジックを使用していましたが、それぞれの言語で実装漏れが発生したこと、横展開の容易さを考慮して正規表現でマッチさせるようにしました。
正規表現であれば、どの言語でも同じようにバリデーションをかけてくれる、そう思っていたところ、大きな勘違いがあったのでブログにします。
環境
- JavaScript
- ES2018
- ES2024
- Python
- 3.12
- Ruby
- 2.7
勘違い
\w
はプログラミング言語によって処理が異なります。
- Python
- Unicode文字にもマッチします
- Ruby
- ASCII文字のみにマッチします
- JavaScript
- ASCII文字のみにマッチします
今回、もともとJavaScriptとRubyを使用していたところに、追加でPythonにも正規表現によるバリデーションを追加したので、差分に引っかかってしまいました。なお、オプションを付ければコントロールは可能なパターンもあります。
# PythonにてASCII文字のみにマッチするオプション import re pattern = re.compile("\w+", re.ASCII)
# JavaScriptにて Unicodeにもマッチさせるオプション(ES2018以降より) const matches = text.match(/\w+/u);
OpenAPIでは特に注意
OpenAPIで型定義ファイルを提供すると、自動生成ファイルを用いればそれぞれの言語ですぐにAPIアクセスできるようになります。しかし、正規表現は言語ごとの解釈の差分を吸収しながら自動生成してくれるわけではありません。\wのメタ表現を使用せずにASCII文字だけマッチしてほしいのか、Unicode文字にもマッチしてほしいのかを明確にすることがオススメです。
[a-zA-Z0-9_]
終わりに
正規表現自体は長期間運用してきたことと、Pythonでもずっと同じ正規表現を使用していたのでハマりました。新機能で手が回っていなかったこともあり、JavaScript
側にバリデーションが入っていなかったのでPython
に値が渡されて、今回初めて気づきました。
今回の件で正規表現に対する苦手意識が強くなりそうです。