メインコンテンツへスキップ
中級12分で読める

正規表現の基本と応用

Linuxコマンドで使える正規表現の基本から応用まで、grep、sed、awkでの活用方法を実例を交えて詳しく解説します。

応用編正規表現regexgrepsedパターンマッチング

🎯 この記事で学べること

  • 1
    正規表現とは何か、なぜ便利なのかを理解できます
  • 2
    基本的なメタ文字(. * [] ^ $ など)の使い方をマスターできます
  • 3
    文字クラスや量指定子を使った柔軟なパターン指定ができるようになります
  • 4
    grep、sed、awkでの正規表現の使い分けが理解できます
  • 5
    実践的なパターン(メール、URL、IPアドレス)の書き方が身につきます

読了時間: 約12

はじめに

こんにちは!今日は「正規表現」について学びましょう。

正規表現(Regular Expression、略して regex)って聞くと、なんだか暗号みたいで難しそう...と思うかもしれません。でも実は、「文字のパターンを表現する方法」というシンプルな概念なんです。

例えば、「電話番号っぽい文字列を全部探したい」「メールアドレスだけ抽出したい」といったときに、正規表現が大活躍します!

正規表現って何?

正規表現は、文字列のパターンを表現するための特別な記法です。

普通の検索との違いを見てみましょう:

  • 普通の検索: 「cat」という文字を探す
  • 正規表現: 「c で始まって t で終わる3文字」を探す

正規表現を使えば、「だいたいこんな感じの文字列」を柔軟に指定できるんです!

🎮 理解度チェック

正規表現の主な用途として適切なものはどれでしょう?

基本のメタ文字を覚えよう

正規表現では、特別な意味を持つ文字(メタ文字)があります。まずは基本的なものから見ていきましょう!

ドット(.)- なんでもいい1文字

# b.t は「b + 何か1文字 + t」
$ echo "bat bit bot but" | grep "b.t"
# → bat bit bot but すべてマッチ

# ca. は「ca + 何か1文字」
$ echo "cat car can cab" | grep "ca."
# → cat car can cab すべてマッチ

ドットは「ワイルドカード」みたいなものですね!

角括弧([])- この中のどれか1文字

# [cbr]at は「c か b か r + at」
$ echo "cat bat rat hat" | grep "[cbr]at"
# → cat bat rat がマッチ(hat は含まれない)

# 範囲も指定できる
$ echo "test123" | grep "[0-9]"  # 数字
$ echo "Hello" | grep "[a-z]"     # 小文字
$ echo "Hello" | grep "[A-Z]"     # 大文字

キャレット(^)とドル($)- 位置を指定

# ^start は「行の最初が start」
$ echo -e "start here\nhere start" | grep "^start"
# → start here だけマッチ

# end$ は「行の最後が end」
$ echo -e "the end\nend of story" | grep "end$"
# → the end だけマッチ

メタ文字を普通の文字として扱いたいときは、バックスラッシュ(\)でエスケープします。例:\. でピリオドを検索

繰り返しを表現する量指定子

アスタリスク(*)- 0回以上

# go*gle は「g + o が0回以上 + gle」
$ echo "ggle gogle google gooogle" | grep "go*gle"
# → すべてマッチ(o が0個でもOK)

プラス(+)- 1回以上(拡張正規表現)

# go+gle は「g + o が1回以上 + gle」
$ echo "ggle gogle google" | grep -E "go+gle"
# → gogle google がマッチ(ggle は o が0個なのでダメ)

疑問符(?)- 0回または1回(拡張正規表現)

# colou?r は「colo + u が0回か1回 + r」
$ echo "color colour" | grep -E "colou?r"
# → color colour 両方マッチ

波括弧()- 回数を指定(拡張正規表現)

# a{3} は「a がちょうど3個」
$ echo "a aa aaa aaaa" | grep -E "a{3}"
# → aaa aaaa がマッチ

# a{2,4} は「a が2個〜4個」
$ echo "a aa aaa aaaa aaaaa" | grep -E "a{2,4}"
# → aa aaa aaaa がマッチ

🎮 理解度チェック

正規表現 'ab*c' にマッチする文字列はどれでしょう?

便利な文字クラス

定義済みの文字クラス

# 数字を探す
[0-9]     または [[:digit:]]

# アルファベットを探す
[a-zA-Z]  または [[:alpha:]]

# 英数字を探す
[a-zA-Z0-9] または [[:alnum:]]

# 空白文字を探す
[ \t\n]   または [[:space:]]

否定文字クラス(〜以外)

# 数字以外
[^0-9]

# 母音以外
[^aeiouAEIOU]

# 空白以外
[^[:space:]]

キャレット(^)を角括弧の中で使うと「〜以外」という意味になります!

実践的なパターンを書いてみよう

メールアドレスを探す

# シンプルなパターン
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}

# 意味:
# [a-zA-Z0-9._%+-]+ : ユーザー名部分(英数字と一部記号)
# @                 : アットマーク
# [a-zA-Z0-9.-]+    : ドメイン名
# \.                : ドット(エスケープが必要)
# [a-zA-Z]{2,}      : トップレベルドメイン(2文字以上)

日本の電話番号を探す

# 様々な形式に対応
0\d{1,4}-?\d{1,4}-?\d{4}

# 意味:
# 0          : 最初は必ず0
# \d{1,4}    : 数字が1〜4個
# -?         : ハイフンがあるかもしれない
# \d{1,4}    : 数字が1〜4個
# -?         : ハイフンがあるかもしれない
# \d{4}      : 数字が4個

URLを探す

# HTTPとHTTPSのURL
https?://[a-zA-Z0-9./?=_%:-]+

# 意味:
# https?     : http または https
# ://        : コロンとスラッシュ2つ
# [a-zA-Z0-9./?=_%:-]+ : URLで使われる文字たち

grepでの正規表現

基本正規表現と拡張正規表現

# 基本正規表現(BRE)- デフォルト
$ grep 'a\+' file.txt    # + をエスケープする必要がある

# 拡張正規表現(ERE)- -E オプション
$ grep -E 'a+' file.txt  # + をそのまま使える

# その他の便利なオプション
$ grep -i 'pattern'  # 大文字小文字を区別しない
$ grep -v 'pattern'  # マッチしない行を表示
$ grep -n 'pattern'  # 行番号も表示

sedでの正規表現活用

置換の基本

# 基本形
$ sed 's/検索パターン/置換文字列/g'

# 日付形式の変換(YYYY-MM-DD → DD/MM/YYYY)
$ echo "2025-01-08" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
# → 08/01/2025

# \1, \2, \3 は括弧でグループ化した部分を参照

HTMLタグを削除

# <tag>content</tag> → content
$ echo "<p>Hello <b>World</b></p>" | sed 's/<[^>]*>//g'
# → Hello World

awkでの正規表現

# パターンにマッチする行だけ処理
$ awk '/error/ {print $0}' log.txt

# 特定のフィールドでマッチ
$ awk '$3 ~ /[0-9]+\.[0-9]+/ {print $1, $3}' data.txt

# ~ は「マッチする」、!~ は「マッチしない」

🎮 理解度チェック

grep で拡張正規表現を使うためのオプションは?

よくある間違いと対策

ドットのエスケープ忘れ

# 間違い:1.5 だけでなく 195 などもマッチしてしまう
$ echo "1.5 195" | grep "1.5"

# 正解:ドットをエスケープ
$ echo "1.5 195" | grep "1\.5"

貪欲マッチに注意

# 問題:最初の < から最後の > まで全部マッチしてしまう
$ echo "<tag>content</tag>" | sed 's/<.*>/X/'
# → X

# 解決策:[^>]* で「> 以外の文字」を指定
$ echo "<tag>content</tag>" | sed 's/<[^>]*>/X/g'
# → XcontentX

行頭・行末の指定

# ^ と $ はそれぞれ行頭・行末を意味する
$ echo -e "test\ntest123\n123test" | grep "^test$"
# → test のみマッチ(完全一致)

正規表現を学ぶコツ

  1. 簡単なパターンから始める

    • まず . * [] ^ $ を使いこなす
    • 慣れたら + ? に挑戦
  2. 実際のデータで練習

    • ログファイルから特定の情報を抽出
    • CSVファイルのデータ処理
  3. 段階的に複雑にする

    • 最初:数字を探す [0-9]
    • 次に:3桁の数字 [0-9]{3}
    • 最後:電話番号 0\d{2,4}-?\d{2,4}-?\d{4}
  4. ツールを活用

    • regex101.com などでパターンをテスト
    • 視覚的に理解できる

正規表現は「習うより慣れろ」です。最初は簡単なパターンから始めて、徐々に複雑なものに挑戦していきましょう!

📝 まとめ

今日は正規表現について学びました!

  • 正規表現は文字列のパターンを表現する強力な方法
  • 基本的なメタ文字:. * [] ^ $
  • 量指定子:* + ? {}
  • grep -E で拡張正規表現が使える
  • 実践的なパターン(メール、電話番号、URL)も正規表現で表現可能

正規表現をマスターすると、テキスト処理の効率が飛躍的に向上します。最初は暗号のように見えても、一つずつ理解していけば必ず使いこなせるようになりますよ!

次はgrepコマンドで、正規表現を使った実践的な検索方法を学んでみませんか?

今日の練習: まず echo "cat bat rat" | grep "b.t" を試してみましょう。次に、自分の名前や好きな単語でパターンを作ってみてください。例えば、母音を . に置き換えたパターンなど!