きり丸の技術日記

技術検証したり、資格等をここに残していきます。

正規表現の\wは使う時は注意。特にOpenAPI

始めに

正規表現には\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に値が渡されて、今回初めて気づきました。

今回の件で正規表現に対する苦手意識が強くなりそうです。