多くのプログラマーには盲点があります。分散システムのデバッグや新しいフレームワークとの格闘には喜んで取り組むのに、わずか10秒で終わるはずの手動のテキスト編集に20分も費やしてしまうのです。その理由は常に同じです。正規表現が、まるで意味不明な記号の羅列(line noise)のように見えるからです。典型的なパターンは、1990年代のモデムから送られてきたかのような、スラッシュやバックスラッシュ、句読点が壁のように並んだものです。この視覚的な混乱が、有能な人々を真に価値のあるスキルから遠ざけています。
幸いなことに、正規表現は難しくありません。密度が高いだけなのです。記号が狭いスペースに膨大な意味を詰め込んでいるため、実際には非常に正確な記述であるにもかかわらず、目はそれをランダムなものとして読み取ってしまいます。正しいメンタルモデルさえ持てば、記号を一つずつ解読しようとするのではなく、それらが描いている「形」を読むようになります。そうすれば、ノイズは完全に消え去ります。
プログラムではなく、パターン
根本的な転換点は、正規表現が実際には何であるかを理解することです。あなたが書くコードのほとんどは手続き型です。「これを行い、次にそれを行い、この条件をチェックし、再びループする」といった具合です。しかし、正規表現は手続きではありません。それはテキストがどのようなものであるべきかを示す、静的なパターンです。検索の方法についての指示を書いているのではなく、マッチングエンジンにスケッチを渡し、実際の作業はエンジンに任せているのです。
次のように、平易な言葉で形を説明していると考えてみてください。
- 5桁の数字。
- メールアドレス。
- 大文字で始まる行。
正規表現が行っているのはそれだけです。ただし、圧縮されたアルファベットを使用しているだけです。\d{5} を見たとき、それは魔法ではありません。「数字が5回繰り返される」という意味です。^[A-Z] を見たときは、「行の先頭に、大文字が1つ続く」という意味です。必要なスキルは暗記ではありません。パターンをパッと見て、それを先ほどの平易な言葉の記述に翻訳することです。一度その翻訳ができるようになれば、威圧感は消え去ります。
実際に失われている時間
人は、十分に苦しんだ後にようやく正規表現を学ぶ傾向があります。より良いアプローチは、午後の時間を無駄にする前に、パターンを必要としているタスクを認識することです。
200ページの文書内にあるすべての日付を見つける必要がある場合、正規表現なら一度のスキャンですべて特定できます。アプリケーションが受け入れる前に、ユーザーが正しいURLを入力したかどうかを検証する必要がある場合、パターンによってアドレスの基本的な形を強制できます。ウェブサイトからコピーしたテキストを整理し、複数のスペースを1つのスペースにまとめたい場合、置換用の正規表現はわずか4文字で済みます。乱雑なサーバーログからデータを抽出する場合、正規表現は非構造化テキストと構造化されたレポートを繋ぐ、唯一の合理的な架け橋となることがよくあります。
採用すべき簡単なルールがあります。もし、手作業で50回もテキスト編集を行おうとしているなら、一旦止まってください。代わりにパターンを書きましょう。手動の繰り返しは遅いだけでなく、信頼性も低いです。47番目の箇所を見逃したり、33番目でタイポをしたりする可能性があります。パターンは一度、正確に作業を行い、そもそも適用しようとしていたルールを文書化することにもなります。
効果的な学習ループ
記憶を頼りに完璧なパターンを打ち込もうとしないでください。そうすると挫折感が高まります。代わりに、構文に迷い込むことなく前進し続けられる、効率的なループに従ってください。
- 言葉で形を説明する。 特殊文字に触れる前に、自分が何をしたいのかを正確に書き出します。「4桁の数字、その後にハイフン、次に2桁の数字、次にハイフン、最後に2桁の数字」といった具合です。明確に言葉にできないものは、パターン化することもできません。
- 初稿を作成する。 最も広範で妥当な記号を使用して、その記述を基本的なパターンに変換します。完璧さを求める必要はありません。プロトタイプを作っているのです。
