ja ja ja ja ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja da ja ja ja en ja ja en ja ja ja ja hbs_lat ja ja ja ja ja ja ja ja ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja en ja ja en ja ja vi ja sv eu ja en en hu ja ja en en pl ja ja jbo hbs_lat en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja
クリアなコードの作り方: 正規表現はマッチしすぎに気をつける - 2015-03-25 - ククログ
これで問題がないと思いますよね?でも、問題があるんです。問題があるのは例えば次のケースです。
eps_file_name = "XXX.eps" pdf_file_name = eps_file_name.sub(/.ps$/i, ".pdf") p pdf_file_name # => "XXX..pdf"
この場合は拡張子が「.eps」なので何もしないで欲しいところですが「..pdf」になっています。
これは正規表現が「マッチしすぎている」からです。ちなみに、マッチしすぎる正規表現は初心者の人がやりがちな雑な正規表現の使い方です。丁寧に正規表現を使えるようになると、「この人はしっかりしているな…!」と一目置かれることでしょう。
マッチしすぎる正規表現
まず、どこがマッチしすぎていたかを確認しましょう。
この正規表現の最初にある「.」が注目するポイントです。「.」は任意の1文字にマッチするので「.」そのものにもマッチしますが、「e」など他の文字にもマッチします。
初級者の人は「マッチするパターンだけを確認して大丈夫」と判断する傾向があるようです1。初級者からステップアップするために、「マッチしすぎていないか」も確認するようにしましょう。
マッチしすぎる正規表現の問題
では、「マッチしすぎる」となにが問題なのでしょうか。1つは、正常なデータを壊れたデータにしてしまうことです。もう1つは、コードを読むときに理解しにくくなることです。
マッチしすぎる正規表現はエラー処理を省略することよりも深刻な問題になることがあります。エラー処理を書いてない場合は(例外機能がある言語の場合は)エラーでプログラムが止まりますが、マッチしすぎる正規表現の場合は正常なデータを壊れたデータにし2、そのまま処理が継続します。問題が発生したときに止めていれば被害が最小限にとどまったり、原因を見つけやすくなりますが、問題が発生したまま処理を継続すると被害が拡大したり、原因究明を難しくしたりしてしまいます。
コードを読んだときに理解しにくくなることもマッチしすぎる正規表現の問題です。「あれ、この処理だとこの正規表現はマッチしすぎる気がするんだけど。。。なにか特別な意図があるんだろうか。。。」と勘ぐってしまい、理解に手間取ってしまいます。
マッチしすぎる正規表現を防ぐポイント
マッチしすぎる正規表現を防ぐ方法はいくつかあります。たとえば次の方法です。
他の人にも確認してもらう。
メタ文字を意識的に注意する。
チームのみんながそれぞれのコードを読む文化になっていると「他の人にも確認してもらう」は実現しやすいでしょう。そうでない場合は、まわりの人にお願いすることになります。
メタ文字は特別な意味のある文字で「.」もメタ文字の1つです。これらを意識的に注意することでマッチしすぎないかを見つけやすくなります。中級者以上の人はこれをやっているはずです。
なお、fluent/fluentd-ui@a28b710のケース(↓)のように式展開後の値にメタ文字が含まれるケースもあるので注意してください。これは中級者でも気づきにくいケースです。
FILE_EXTENSION = ".conf".freeze # ... @note = note || Note.new(file_path.sub(/#{FILE_EXTENSION}$/, Note::FILE_EXTENSION))
ちなみに、今回の例ではファイル名の終端を表すために「$」を使っていましたが、Rubyの場合は「\z」の方が適切です。違いは「$」は行末、「\z」は文字列の最後を示すという点です。しかし、通常はファイル名に改行は入らないので、「拡張子を変更する」という機能であれば「妥当なファイル名を渡すのは呼び出し側の責任」と設計することで「$」でも問題なくすることもできます。
初級者がついやってしまいがちなマッチしすぎる正規表現とその問題、およびその対策について説明しました。中級者を目指している人は意識してみてください。
そもそも確認もしない人もいるので、確認していることはとてもよいことです。 ↩
今回の例のように置換した場合は直接データが壊れますが、正規表現を入力のバリデーションに使っている場合は壊れたデータを正常なデータと扱ってしまったりします。 ↩
現在クリアコードではソフトウェア開発者を募集しています! フリーソフトウェア開発での開発の仕方をベースに、成果や知識を公開し共有しながら業務に携われます。
Software Design 4月号の紹介
Git でコミットメールを配信する方法
Apache Arrow
milter manager
ククログの記事はCC BY-SA 4.0とGFDLのデュアルライセンスで自由に利用できます。
クリアコードはプログラミングが楽しいソフトウェア開発者を1名募集しています。
クリアコードは「クリアコードをいい感じにする人」を1名募集しています。
クリアコードはフリーソフトウェア開発で培った技術力を提供しています。特にMozilla製品(Mozilla FirefoxとMozilla Thunderbird)とRubyとGroonga(全文検索)に関連した開発を得意としています。