正規表現・テキスト処理 ・ 中級実務パターン集——IP・日付・ログ
実務でよく出てくる正規表現には、ある程度決まった「型」があります。IPアドレス風・日付・時刻・エラー行の抽出といった定番パターンを、自分で組み立てられなくても「読んで意味が分かる」レベルまで引き上げます。前後の文脈を見る-A -B -Cと、範囲を食べすぎる貪欲マッチへの対策もあわせて身につけましょう。
正規表現を実務で使うとき、毎回ゼロから組み立てる必要はない。IPアドレスや日付のような形は、ほぼ決まったパターンで書けるからだ。ここでは「作れる」より先に「読める」を目標にする。
誰かが書いた正規表現を見たときに、それが何を探そうとしているのか見当がつけば、ログ調査やコードレビューで十分に役立つ。まずはよく出てくる型を一通り眺めてみよう。
💡ポイント実務の正規表現は、初見で完璧に組み立てるものではなく、よく出る型を知っていて「読める」ことの方が価値が大きい。
🌐 IPアドレス風のパターン
IPv4アドレスは0〜255の数字が4つ、ドットで区切られた形をしている。これを正規表現で表す定番の書き方が \b([0-9]{1,3}\.){3}[0-9]{1,3}\b だ。
([0-9]{1,3}\.) は「1〜3桁の数字+ドット」という塊で、これを{3}で3回繰り返す。最後にドットなしの数字が1つ続く形になっている。\bは単語の境界で、前後に別の数字や文字がくっついていないことを保証する。
⚠つまずきこのパターンはあくまで「IPアドレスっぽい形」を緩く判定しているだけだ。各数字が0〜255の範囲に収まっているかまではチェックしていないので、999.999.999.999のような実在しない値にもマッチしてしまう。厳密な検証が必要な場面では別の手段(専用のバリデーション処理)を使うべきだ。
▶例$ grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log → IPアドレスらしき並びを含む行を抽出する。ただし前述の通り、数値範囲までは検証していない。
📅 日付と時刻のパターン
YYYY-MM-DD形式の日付も、実務ログで頻出する型だ。書き方は [0-9]{4}-[0-9]{2}-[0-9]{2} のように、4桁・2桁・2桁の数字をハイフンでつなぐ形が基本になる。
時刻はHH:MM:SSの形が多く、[0-9]{2}:[0-9]{2}:[0-9]{2} と表せる。日付と時刻をひとつなぎで探したいなら、この2つを空白でつなげて並べればよい。
▶例$ grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' server.log → 2024-07-03 09:15:42 のような日時の並びを含む行を抽出する。
✓コツ桁数が決まっている数字の並びは、まず{n}で桁数を固定してから区切り文字(ハイフンやコロン)でつなぐ、という組み立て方をすると迷いにくい。
🚨 エラー行の抽出と前後の文脈
ログ調査でもっとも頻繁に使うのが、ERRORやWARNといった重要度の高い行を拾う処理だ。交替|と組み合わせれば、複数のキーワードを一度に拾える。
▶例$ grep -E 'ERROR|WARN' server.log → ERRORまたはWARNという文字列を含む行を抽出する。
問題は、エラー行だけを見ても「その前後で何が起きていたか」が分からないことだ。ここで役立つのが文脈を表示するオプションで、-Aは後の行、-Bは前の行、-Cは前後両方を追加で表示する。
▶例$ grep -E -A 2 'ERROR|WARN' server.log → ERRORまたはWARNの行に加えて、その直後の2行も一緒に表示する。エラーの後に何が起きたかを追いやすくなる。
💡ポイント-A n(after)は後ろにn行、-B n(before)は前にn行、-C n(context)は前後にn行ずつを、マッチした行と一緒に表示する。原因調査では-Bが、影響範囲の確認では-Aが特に役立つ。
🔗たとえマッチした行だけを見るのは、事件現場の写真1枚だけを見るようなもの。-A -B -Cは、その前後の防犯カメラ映像も一緒に見せてくれるイメージだ。
🍽️ 貪欲さという食べすぎ問題
正規表現に慣れてきた頃によく遭遇するのが、.*が思ったより広い範囲にマッチしてしまう現象だ。これを貪欲マッチと呼ぶ。
たとえば"..."のように二重引用符で囲まれた最初の文字列だけを取り出したいとする。".*"と書くと、.*はできるだけ長くマッチしようとする性質があるため、複数の引用符ペアがある行では最初の"から最後の"までを一気に食べてしまうことがある。
🔗たとえ.*は満腹になるまで食べ続ける性格だと思うとよい。「次の"が来たらそこで止めて」と指示しない限り、行の終わり近くまで食べ進んでしまう。
この対策としてよく使われるのが、区切り文字そのものを除外した文字クラスに置き換える方法だ。"の代わりに"以外の文字だけを表す[^"]*を使えば、最初の"に出会った時点で止まってくれる。
▶例対象文字列 "foo" and "bar" に ".*" を当てると "foo" and "bar" 全体にマッチしてしまう。[^"]* を使った "[^"]*" に変えると "foo" だけにマッチする。
⚠つまずき[^"]*は「引用符以外の文字が0回以上」という意味で、貪欲マッチそのものをやめさせるわけではない。あくまで「食べていい範囲」を区切り文字の手前までに制限しているだけだ、と理解しておくと応用が利く。
✓コツ.*を書いた後で意図しない範囲までマッチしてしまったら、まず「本当は何の文字で区切りたかったか」を考え、その文字を除外した文字クラスに置き換えられないか検討するとよい。
🧩 型を知れば読み解ける
IPアドレス風・日付・時刻・エラー行・貪欲さへの対策、この5つの型を押さえておけば、実務のログや設定ファイルで出会う正規表現の大半は「何をしようとしているか」が読み解けるようになる。
💡ポイント完璧な検証パターンを自分で作れることよりも、既存のパターンを見て緩い判定なのか厳密な判定なのかを見極められることの方が、実務では長く役立つ。
ここまでの正規表現トラックで、メタ文字・量指定子・grep・sed・awk・グループ化・実務パターンと一通りの道具を見てきた。あとは実際のログやファイルに向き合いながら、少しずつ手に馴染ませていってほしい。
この項目に出てくる用語
貪欲マッチどんよくまっち.*などの量指定子が、可能な限り長い範囲にマッチしようとする性質。
文脈オプションぶんみゃくおぷしょんgrepでマッチした行の前後の行もあわせて表示する-A -B -Cオプションの総称。
関連コマンド
▶ 学習アプリでこの続きを学ぶ・演習する