正規表現とは
正規表現(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
以下のパターンを抽出してください:
- 404エラーのログ行
- IPアドレス部分のみ
- タイムスタンプ部分
- リクエストメソッド(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. 有効なメールアドレス(簡易版)
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 を使った高度なテキスト変換について学びます。