正規表現入門

正規表現入門 とは

正規表現をターミナルで実践的に学びます。文字列検索や置換をマスターしましょう。本レッスンでは、正規表現入門 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

正規表現 (regular expression、略して regex) は、文字列のパターンを表現するための小さな言語です。grepsedawk といったテキスト処理ツールは、いずれも内部で正規表現を解釈し、行をフィルタしたり置換したりします。エディタの検索、プログラミング言語の文字列マッチ、URL ルーティング、フォーム入力のバリデーションなど、活躍する場所は広範囲にわたります。

ここでは Linux で grep が標準で使う 基本正規表現 (BRE) と、-E で有効になる 拡張正規表現 (ERE) の両方を取り上げ、よく使うメタ文字に慣れます。

基本構文

ターミナル

grep 'パターン' ファイル grep -E 'パターン' ファイル # 拡張正規表現

パターンは必ずシングルクォートで囲みます。シェルの展開を防ぐためです。

主要メタ文字

記号意味BRE での扱い
.任意の 1 文字そのまま使える
*直前の 0 回以上の繰り返しそのまま使える
^行頭そのまま使える
$行末そのまま使える
[abc]文字クラスそのまま使える
[^abc]否定文字クラスそのまま使える
+直前の 1 回以上BRE では \+、ERE ではそのまま
?直前の 0 か 1 回BRE では \?、ERE ではそのまま
| / ``選択
(...)グルーピングBRE では \(...\)、ERE では ()

動作の図解

diagram (will load when visible)

アンカー

^ は行頭、$ は行末にマッチします。

ターミナル

$ grep '^Hello' /tmp/file.txt Hello world Hello there $ grep 'world$' /tmp/file.txt Hello world goodbye world

両端を組み合わせると完全一致が表現できます。

ターミナル

$ grep '^OK$' /tmp/status.txt OK

文字クラス

[] の中に複数の文字を並べると、そのいずれかにマッチします。範囲指定もできます。

ターミナル

$ grep '[0-9]' /tmp/data.txt user1 user123 $ grep '[A-Za-z]' /tmp/data.txt admin

[^...] は否定で、含まれない文字にマッチします。

ターミナル

$ grep '^[^#]' /etc/profile # コメント以外の行

POSIX 文字クラスを使うと意図が明確になります。[[:digit:]] (数字)、[[:alpha:]] (英字)、[[:space:]] (空白) など。ロケール対応の場面で重宝します。

繰り返し

* は 0 回以上、+ は 1 回以上、? は 0 か 1 回。+? を素直に書きたい場合は grep -E (拡張正規表現) を使うのが楽です。

ターミナル

$ echo -e "a\nab\naab\nb" | grep -E 'a+b' ab aab

選択とグルーピング

ERE で (cat|dog) のように書くと「cat または dog」にマッチします。

ターミナル

$ echo -e "cat\ndog\nbird" | grep -E '(cat|dog)' cat dog

エスケープ

メタ文字そのものを検索したいときは \ でエスケープします。たとえば「ピリオド」を検索するには \. と書きます。

ターミナル

$ echo -e "3.14\n314" | grep '\.' 3.14

grep の BRE と grep -E の ERE は同じ機能ですが書き方が違います。迷ったら -E を付ければ多くの言語の正規表現と感覚が近くなります。egrepgrep -E の旧名で、現代でも使えますが新しいスクリプトでは grep -E が推奨されます。

やってみよう

演習では複数行のデータを作り、行頭マッチ ^ を試してみます。次のレッスンで実際に grep と組み合わせて応用していきます。

貪欲マッチに気をつける

.* は「任意の文字を 0 文字以上」にマッチしますが、できるだけ長く取ろうとします (貪欲)。HTML の <a>...</a> の中身を取り出すつもりで <.*> と書くと、行内の最後の > まで一気に取ってしまうことがあります。

ターミナル

$ echo '<a href="x"><b>x</b></a>' | grep -oE '<.*>' <a href="x"><b>x</b></a>

対策として、PCRE が使える環境では .*? (非貪欲) を使うか、<[^>]*> のように「> 以外を集める」表現に書き換えます。

まとめ

  • 正規表現は .*^$[] などのメタ文字でパターンを表現する
  • +?|() を素直に使うには grep -E (拡張正規表現) を使う
  • POSIX 文字クラス [[:digit:]] などは可読性が高くおすすめ
  • メタ文字そのものを検索するときは \. のようにエスケープする
  • .* は貪欲にマッチするので、欲張りすぎないよう注意する

次のレッスン

次は grep 応用:正規表現 で、正規表現をターミナルで実践的に学びます を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 正規表現入門 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 正規表現入門 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

課題

  1. echo でテストデータを作る
  2. grep でアンカー ^ を使う
  3. apple と ant の 2 行だけ出力する

ヒント

script.sh
script.sh
学習モード
script.sh
ターミナル出力