正規表現入門
正規表現入門 とは
正規表現をターミナルで実践的に学びます。文字列検索や置換をマスターしましょう。本レッスンでは、正規表現入門 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
正規表現 (regular expression、略して regex) は、文字列のパターンを表現するための小さな言語です。grep、sed、awk といったテキスト処理ツールは、いずれも内部で正規表現を解釈し、行をフィルタしたり置換したりします。エディタの検索、プログラミング言語の文字列マッチ、URL ルーティング、フォーム入力のバリデーションなど、活躍する場所は広範囲にわたります。
ここでは Linux で grep が標準で使う 基本正規表現 (BRE) と、-E で有効になる 拡張正規表現 (ERE) の両方を取り上げ、よく使うメタ文字に慣れます。
基本構文
ターミナル
grep 'パターン' ファイル
grep -E 'パターン' ファイル # 拡張正規表現パターンは必ずシングルクォートで囲みます。シェルの展開を防ぐためです。
主要メタ文字
| 記号 | 意味 | BRE での扱い |
|---|---|---|
. | 任意の 1 文字 | そのまま使える |
* | 直前の 0 回以上の繰り返し | そのまま使える |
^ | 行頭 | そのまま使える |
$ | 行末 | そのまま使える |
[abc] | 文字クラス | そのまま使える |
[^abc] | 否定文字クラス | そのまま使える |
+ | 直前の 1 回以上 | BRE では \+、ERE ではそのまま |
? | 直前の 0 か 1 回 | BRE では \?、ERE ではそのまま |
| / ` | ` | 選択 |
(...) | グルーピング | BRE では \(...\)、ERE では () |
動作の図解
アンカー
^ は行頭、$ は行末にマッチします。
ターミナル
$ 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を付ければ多くの言語の正規表現と感覚が近くなります。egrepはgrep -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 つができることを確認しましょう。
- 正規表現入門 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 正規表現入門 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
課題
- echo でテストデータを作る
- grep でアンカー ^ を使う
- apple と ant の 2 行だけ出力する