メインコンテンツへスキップ
レッスン 1 / 8推定時間: 30

正規表現の基礎と実践

正規表現の基本概念から高度なパターンマッチングまで、テキスト処理の基盤となる技術を習得します

このレッスンの学習目標

  • 正規表現の基本文法を理解する
  • 実践的なパターンマッチングができる
  • grep、sed、awk での正規表現活用法を学ぶ
  • 複雑な文字列パターンを構築できる

正規表現とは

正規表現(Regular Expression, regex)は、文字列のパターンを記述するための言語です。テキスト検索、置換、バリデーションなど、様々な場面で強力な武器となります。

正規表現の基本概念

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

正規表現の種類:

  • BRE (Basic Regular Expression): sed、grep の標準
  • ERE (Extended Regular Expression): egrep、awk で使用
  • PCRE (Perl Compatible Regular Expression): より高機能

基本的なメタ文字

文字マッチング

# リテラル文字
grep "hello" sample.txt  # "hello" を含む行

# 任意の1文字(.)
grep "h.llo" sample.txt  # h と llo の間に任意の1文字

# 文字クラス
grep "[Hh]ello" sample.txt  # H または h で始まる hello
grep "[0-9]" sample.txt     # 数字を含む行
grep "[a-z]" sample.txt     # 小文字を含む行
grep "[^0-9]" sample.txt    # 数字以外を含む行

定義済み文字クラス

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
パターン意味
[[:digit:]]数字 (0-9)grep '[[:digit:]]'
[[:alpha:]]アルファベットgrep '[[:alpha:]]'
[[:alnum:]]英数字grep '[[:alnum:]]'
[[:space:]]空白文字grep '[[:space:]]'
[[:punct:]]句読点grep '[[:punct:]]'
# 使用例
grep '[[:digit:]]' patterns.txt    # 数字を含む行
grep '[[:punct:]]' patterns.txt    # 句読点を含む行
grep '[[:space:]]' patterns.txt    # 空白を含む行

アンカー(位置指定)

行の開始と終了

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 行の開始(^)
grep "^start" anchors.txt    # 行の開始が"start"

# 行の終了($)
grep "end$" anchors.txt      # 行の終了が"end"

# 完全一致
grep "^start of line$" anchors.txt

# 空行
grep "^$" anchors.txt

# 行頭の数字
grep "^[0-9]" sample.txt

単語境界

# 単語境界(\b)- GNU grep
grep "\\bworld\\b" sample.txt  # "world" という完全な単語

# 単語の開始(\<)
grep "\\<world" sample.txt     # "world" で始まる単語

# 単語の終了(\>)
grep "world\\>" sample.txt     # "world" で終わる単語

量詞(Quantifiers)

基本的な量詞

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# ? : 0回または1回
egrep "a?" quantity.txt        # a が0回または1回

# * : 0回以上
grep "a*" quantity.txt         # a が0回以上

# + : 1回以上(Extended RE)
egrep "a+" quantity.txt        # a が1回以上

# {n} : ちょうどn回
egrep "a{3}" quantity.txt      # a がちょうど3回

# {n,} : n回以上
egrep "a{2,}" quantity.txt     # a が2回以上

# {n,m} : n回以上m回以下
egrep "a{2,4}" quantity.txt    # a が2〜4回

貪欲マッチング vs 非貪欲マッチング

# 貪欲マッチング(デフォルト)
echo "<tag>content</tag>" | grep -o "<.*>"  # 全体にマッチ

# 最短マッチング(一部のツールで対応)
echo "<tag>content</tag>" | grep -o "<[^>]*>"  # タグのみ

グループ化と選択

グループ化

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# グループ化()
egrep "(cat|dog)" groups.txt   # "cat" または "dog"

# 複数グループ
egrep "(cat|dog)(s)?" groups.txt  # "cat" または "dog" の後に s が0回または1回

# 後方参照
sed 's/\(cat\)\(dog\)/\2\1/' groups.txt  # "catdog" を "dogcat" に

選択(OR)

# | を使った選択(Extended RE)
egrep "cat|dog" groups.txt

# BREでの選択(\| エスケープが必要)
grep "cat\\|dog" groups.txt

実践的なパターン例

メールアドレス

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# 基本的なメールアドレスパターン
egrep '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' emails.txt

# より厳密なパターン
egrep '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' emails.txt

IPアドレス

# IPv4アドレス
echo -e '192.168.1.1\n10.0.0.1\n256.1.1.1\n192.168.1' > ips.txt

# 基本的なIPパターン
egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ips.txt

# より厳密なIPパターン
egrep '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' ips.txt

日付形式

# 様々な日付形式
echo -e '2024-01-15\n01/15/2024\n15-Jan-2024\n2024年1月15日' > dates.txt

# YYYY-MM-DD 形式
egrep '[0-9]{4}-[0-9]{2}-[0-9]{2}' dates.txt

# MM/DD/YYYY 形式
egrep '[0-9]{2}/[0-9]{2}/[0-9]{4}' dates.txt

# 日本語形式
egrep '[0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日' dates.txt

正規表現のツール別差異

grep vs egrep vs fgrep

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log
# Basic RE (grep)
grep "test+" regex_test.txt        # + はリテラル文字として扱われる
grep "test\\+" regex_test.txt      # + を量詞として使用

# Extended RE (egrep)
egrep "test+" regex_test.txt       # + が量詞として動作

# Fixed strings (fgrep)
fgrep "test+" regex_test.txt       # 正規表現を使わない高速検索

sed での正規表現

# sed の基本的な使用法
sed 's/old/new/' regex_test.txt           # 最初のマッチのみ
sed 's/old/new/g' regex_test.txt          # すべてのマッチ
sed 's/\(test\)\(.*\)/\1_modified\2/' regex_test.txt  # グループ化と後方参照

awk での正規表現

# awk での正規表現マッチング
awk '/pattern/ {print}' regex_test.txt     # パターンマッチング
awk '$1 ~ /pattern/ {print}' regex_test.txt # 特定フィールドのマッチング
awk '$0 !~ /pattern/ {print}' regex_test.txt # 否定マッチング

実践演習

演習1: ログファイル解析

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

以下のパターンを抽出してください:

  1. 404エラーのログ行
  2. IPアドレス部分のみ
  3. タイムスタンプ部分
  4. リクエストメソッド(GET, POST など)

解答例:

# 1. 404エラーのログ行
grep " 404 " access.log

# 2. IPアドレス部分のみ
egrep -o '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' access.log

# 3. タイムスタンプ部分
egrep -o '\[[^]]*\]' access.log

# 4. リクエストメソッド
egrep -o '"[A-Z]+ ' access.log | tr -d '"'

演習2: CSVデータの検証

CommandAcademy Terminal
Welcome to CommandAcademy Terminal!
Type "help" to see available commands.
user@cmdac:~$

ファイルツリー

/
etc
hosts35B
passwd76B
home
user
tmp
usr
bin
share
var
log

以下の検証を行ってください:

  1. 有効なメールアドレスの行
  2. 有効な電話番号の行(様々な形式を許可)
  3. 年齢が数値の行
  4. すべてのフィールドが適切な形式の行

解答例:

# 1. 有効なメールアドレス(簡易版)
egrep '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' data.csv

# 2. 有効な電話番号(様々な形式)
egrep '(\+?[0-9-]+\.?){3,}' data.csv

# 3. 年齢が数値
egrep ',[0-9]+$' data.csv

# 4. 完全性チェック(各フィールドに適切な値)
egrep '^[^,]+,[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,},.*[0-9].*,[0-9]+$' data.csv

正規表現のデバッグとテスト

パターンのテスト

# 段階的にパターンを構築
echo "test123@example.com" | grep -o '[a-z]'      # 小文字のみ
echo "test123@example.com" | grep -o '[a-z0-9]'   # 英数字
echo "test123@example.com" | grep -o '[a-z0-9]@'  # @ 前の文字
echo "test123@example.com" | grep -o '[a-z0-9]*@' # @ 前の文字列

# マッチした部分のみ表示
egrep -o 'pattern' file.txt

# 行番号付きで表示
grep -n 'pattern' file.txt

# マッチしない行
grep -v 'pattern' file.txt

正規表現ツールの活用

# Perl互換の正規表現(利用可能な場合)
pcregrep -o 'pattern' file.txt

# より詳細な情報
grep --color=always 'pattern' file.txt

パフォーマンスの考慮事項

効率的な正規表現

# 非効率な例
grep ".*very.*long.*pattern.*" large_file.txt

# 効率的な例
grep "very" large_file.txt | grep "long" | grep "pattern"

# fgrepの活用(固定文字列検索)
fgrep "exact_string" large_file.txt  # 正規表現を使わない高速検索

# コンパイル済み正規表現(一部のツール)
grep -F -f pattern_file.txt input_file.txt  # パターンファイル使用

まとめ

このレッスンでは、正規表現の基本から実践的な使用法まで学びました:

  • 基本的なメタ文字と文字クラス
  • アンカーと量詞の使用
  • グループ化と選択の活用
  • 実践的なパターン例
  • ツール別の違いと使い分け
  • パフォーマンスの最適化

正規表現は強力ですが、複雑になりがちです。段階的にパターンを構築し、テストしながら進めることが重要です。

💡 次のレッスンでは、sed を使った高度なテキスト変換について学びます。