「特定のパターンに一致する文字列だけを探したい」「同じ形式のデータをまとめて置換したい」という場面で役立つのが正規表現だ。
正規表現は記号が多いため難しく見えるが、最初からすべて覚える必要はない。よく使う基本構文と使い方の流れを押さえれば、テキスト検索、置換、文字列抽出、入力チェックを効率よく進められる。この記事では、正規表現とは何か、基本構文、サクラエディタなどで使える実践的な置換例、うまく動かない時の確認ポイントまで初心者向けに解説する。
正規表現とは文字列のパターンを表す書き方
正規表現とは、文字列の並び方や条件を記号で表すための書き方だ。「数字4桁」「@を含む文字列」「特定の形式の日付」のような条件を、短いパターンとして指定できる。
たとえば、[0-9]{4} は「数字が4回続く」という意味になる。これを使うと、文章やデータの中から郵便番号、日付、商品コードのような一定の形式を持つ文字列を探しやすくなる。
正規表現は、テキストエディタの検索・置換、プログラムの入力チェック、ログ解析、CSV整形など、文字列を扱う多くの作業で使われている。
正規表現を使うメリット・デメリット
正規表現は、繰り返しのテキスト処理を効率化できる一方で、記号の意味を誤ると意図しない範囲まで処理してしまうことがある。
正規表現を使うメリット
正規表現を使う大きなメリットは、複雑な条件の検索・置換を一度の操作で行えることだ。
- 複雑な条件で文字列を検索・抽出できる
- 同じ形式のデータをまとめて置換できる
- 入力チェックを短い条件式で書ける
- 手作業による修正漏れや入力ミスを減らせる
たとえば、何百行もあるデータから「数字だけの行」を探す場合、目視で確認すると時間がかかる。正規表現なら ^[0-9]+$ のように条件を指定するだけで、対象の行をまとめて探せる。
正規表現のデメリット・苦手なこと
正規表現は、慣れるまで読み書きが難しい点がデメリットだ。特に .、*、+、? のような記号は意味を間違えやすく、意図しない文字列にもマッチすることがある。
また、HTMLやXMLのように入れ子構造を持つデータを厳密に解析する用途には向いていない。単純なタグの中身を取り出す程度なら使える場合もあるが、構造を正確に扱う必要があるならHTMLパーサーなど専用の仕組みを使う方が安全だ。
正規表現を使う前に知っておきたい基本の流れ
正規表現は、いきなり複雑なパターンを書くよりも、小さく試しながら広げる方が失敗しにくい。
まず普通の検索で対象の文字列を確認する
最初に、検索したい文字列や置換したいデータの共通点を確認する。たとえば「2024/04/01」「2024-04-01」のような日付を探したいなら、年・月・日が数字で、区切りが / または - になっている点が共通している。
この共通点を整理してから正規表現にすると、無駄に複雑なパターンを書かずに済む。
小さな正規表現から試す
最初から完成形を書こうとせず、まずは数字だけ、次に区切り文字、最後に行全体という順番で条件を足すと理解しやすい。
[0-9]{4}
[0-9]{4}[/\-][0-9]{2}
^[0-9]{4}[/\-][0-9]{2}[/\-][0-9]{2}$
このように段階を分けると、どの部分で想定外のマッチが起きているかを見つけやすくなる。
置換前に結果を確認してから実行する
置換は一括でデータを書き換えるため、事前確認が重要だ。まず検索だけを実行し、マッチする範囲が正しいか確認してから置換する。重要なファイルでは、作業前にコピーを残しておくと戻しやすい。
正規表現を試せるツール
初心者は、正規表現の結果をすぐ確認できるツールで試してから、テキストエディタやプログラムに移すと理解しやすい。
ブラウザ上の正規表現チェッカーは、入力した正規表現がどの文字列にマッチするかを確認しやすい。実際のファイルを一括置換する前に、短いサンプル文字列で試す用途に向いている。
正規表現の基本構文
正規表現でよく使う記号をまとめる。最初から暗記するより、検索・置換の例と一緒に必要なものから覚えるとよい。
よく使う基本の記号一覧
| パターン | 意味 | 例 |
|---|---|---|
. | 任意の1文字。多くの環境では改行を除く | a.c → abc, axc |
* | 直前の文字が0回以上 | ab*c → ac, abc, abbc |
+ | 直前の文字が1回以上 | ab+c → abc, abbc |
? | 直前の文字が0回または1回 | ab?c → ac, abc |
{n} | 直前の文字がちょうどn回 | [0-9]{4} → 4桁の数字 |
{n,m} | 直前の文字がn〜m回 | [0-9]{2,4} → 2〜4桁の数字 |
^ | 行の先頭 | ^abc → abc で始まる行 |
$ | 行の末尾 | abc$ → abc で終わる行 |
[abc] | a、b、c のいずれか1文字 | [aeiou] → 母音1文字 |
[^abc] | a、b、c 以外の1文字 | [^0-9] → 数字以外 |
[a-z] | a から z までの範囲の1文字 | [A-Za-z] → 英字1文字 |
(...) | グループ化・キャプチャ | (abc)+ → abc の繰り返し |
\d | 数字1文字。環境によって扱いが異なる場合がある | \d{4} → 4桁の数字 |
\s | 空白文字 | ^\s*$ → 空白行 |
\ | エスケープ | \. → ドット文字そのもの |
OR条件を表す場合は、縦線のパイプを使う。たとえば cat|dog と書くと、cat または dog にマッチする。パイプ記号そのものを検索したい場合は、\| のようにエスケープする。
エスケープが必要な文字
正規表現では、一部の記号が特別な意味を持つ。そのため、記号そのものを検索したい場合は、先頭に \ を付けてエスケープする。
| 文字 | エスケープ後 | 用途の例 |
|---|---|---|
. | \. | example.com のドットをそのまま検索する |
* | \* | * 記号そのものを検索する |
+ | \+ | C++ の + を検索する |
? | \? | URL の ? を検索する |
( ) | \( \) | (備考) のかっこをそのまま検索する |
[ ] | \[ \] | [重要] の角かっこをそのまま検索する |
{ } | \{ \} | {A001} の波かっこをそのまま検索する |
| 縦線(パイプ) | | | A|B の縦線をそのまま検索する |
^ | \^ | ^ 記号そのものを検索する |
$ | \$ | 金額表記の $ を検索する |
\ | \\ | バックスラッシュ自体を検索する |
特に .、[、]、(、)、?、+ は検索時によく使う一方で、正規表現の特殊な意味として解釈されやすい。思った結果にならない時は、まずエスケープ漏れを確認するとよい。
キャプチャグループは置換で値を再利用できる
(...) で囲んだ部分は「キャプチャグループ」として記憶され、置換時に再利用できる。たとえば、^([^ ]+) (.+)$ で検索すると、スペース前の文字列が $1、スペース後の文字列が $2 として扱える。
| 記法 | 意味 |
|---|---|
$1, $2 | 置換後の参照。サクラエディタなどで使われる |
\1, \2 | 一部ツール・言語で使われる参照 |
参照方法はツールや言語によって異なる。サクラエディタでは $1、$2 の形を使う例が多いが、別の環境では \1、\2 を使う場合もある。
正規表現の使い方:検索・抽出・置換の実践例
ここからは、テキストエディタや正規表現チェッカーで試しやすい実践例を紹介する。まず検索で対象を見つけ、必要に応じてキャプチャグループを使って置換する流れで考えると理解しやすい。
検索で条件に合う文字列を探す
検索では、対象の文字列がどのような形式になっているかを正規表現で指定する。
| 目的 | 正規表現 | 説明 |
|---|---|---|
| 数字のみの行 | ^[0-9]+$ | 行全体が数字だけの場合にマッチ |
| 空白行 | ^\s*$ | 空白やタブだけの行にマッチ |
| メールアドレス(簡易) | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} | user@example.com のような形式にマッチ |
| 日付形式 | ^[0-9]{4}[/\-][0-9]{2}[/\-][0-9]{2}$ | 2024/01/01 または 2024-01-01 にマッチ |
メールアドレスや日付の正規表現は、あくまで簡易チェックとして使うのが現実的だ。存在するメールアドレスか、実在する日付かまで正確に判定したい場合は、プログラム側の検証と組み合わせる必要がある。
文字列と文字列の間にある文字列を取得する
2つの文字列に挟まれた部分を取り出すには、開始文字列(.*?)終了文字列 のように書く。(.*?) が、挟まれた中身をキャプチャグループとして記憶する。
例:<div>こんにちは</div> から「こんにちは」だけを取得する
検索:<div>(.*?)</div>
置換:$1
ポイントは ? を付けた非貪欲マッチを使うことだ。.* はできるだけ長くマッチしようとするため、同じ開始・終了文字列が複数ある場合に余計な範囲まで含めることがある。.*? を使うと最短の範囲にマッチしやすくなる。
| 目的 | 正規表現 | 取得対象の例 |
|---|---|---|
[ と ] の間 | \[(.*?)\] | [東京都] → 東京都 |
" と " の間 | "(.*?)" | "hello" → hello |
( と ) の間 | \((.*?)\) | (備考欄) → 備考欄 |
<div> と </div> の間 | <div>(.*?)</div> | <div>こんにちは</div> → こんにちは |
取得した内容は、置換欄で $1 として呼び出せる。たとえば <div>(.*?)</div> で検索し、置換に $1 を指定すると、<div>こんにちは</div> を こんにちは に一括変換できる。
前後の文字列を含めずに中身だけを探す
前後の決まった文字列を条件にしつつ、検索結果には中身だけを表示したい場合は、先読みと後読みを使う方法がある。
検索:(?<=<div>)[^<]*(?=</div>)
この正規表現では、(?<=<div>) が「直前に <div> がある場所」を条件にする後読み、(?=</div>) が「直後に </div> がある場所」を条件にする先読みだ。中央の [^<]* は、次の < が出てくるまでの文字列にマッチする。
ただし、先読み・後読みはツールや正規表現エンジンによって対応状況が異なる。特に後読みは、使える環境でも「長さが固定された条件だけ対応」のような制限がある場合がある。
属性付きのHTMLから特定の値を取り出す場合は、先読み・後読みだけにこだわらず、キャプチャグループで中身を取り出す方が扱いやすい。
例:「姓(family name)」の値だけを取り出す
検索:姓\(family name\)</td><td[^>]*><div>([^<]*)</div>
置換:$1
<td[^>]*> と書くことで、<td class="..."> のように属性が付いている場合にも対応しやすくなる。ただし、HTML全体を厳密に解析する用途では正規表現だけに頼らず、HTMLパーサーの利用を検討したい。
エスケープ文字を一括変換する
記号をそのまま正規表現で扱いたい時は、特殊文字の前に \ をまとめて追加すると効率がよい。入力された文字列を「そのまま検索できる文字列」として使いたい場面で役立つ。
例:a+b(c).txt を a\+b\(c\)\.txt に変換する
検索:([\\.^$|?*+(){}\[\]])
置換:\\$1
このパターンは、正規表現で特別な意味を持つ文字を1文字ずつキャプチャし、置換時に先頭へ \ を付ける。+、(、)、. などをまとめて一括変換したい時に使いやすい。
置換欄でのバックスラッシュの扱いはツールによって異なる場合がある。サクラエディタ以外で使う場合は、短いサンプル文字列で置換結果を確認してから実行するとよい。
Windowsのファイル名に使えない文字を確認・変換する
Windowsでは、ファイル名に \ / : * ? " < > | を使えない。まず、以下の正規表現で禁止文字が含まれているか確認する。
検索:[\\/:*?"<>|]
マッチした行やセルには禁止文字が含まれている。禁止文字をまとめて置換する場合は、以下のように _ へ変換すると扱いやすい。
例:売上:2024/04?確定版*.xlsx を 売上_2024_04_確定版_.xlsx に変換する
検索:[\\/:*?"<>|]
置換:_
内容の意味をできるだけ残したい場合は、半角記号を全角記号へ置き換える方法もある。たとえば、\ は ¥、/ は /、: は :、* は *、? は ?、" は ”、< は <、> は >、| は | に置き換えると、禁止文字を避けつつ意味が伝わりやすいファイル名に整えやすい。
ただし、Windowsでは末尾のピリオドや空白、CON や PRN などの予約名もファイル名として使えない。厳密にファイル名を整えたい場合は、これらも別途確認するとよい。
姓名の順序を入れ替える
キャプチャグループを使うと、文字列の順序を入れ替えられる。
例:田中 太郎 → 太郎 田中
検索:^([^ ]+) (.+)$
置換:$2 $1
([^ ]+) はスペース以外の文字の連続、(.+) は残りの文字列にマッチする。置換欄で $2 $1 と書くことで、2番目に取得した文字列を先に出力できる。
CSVの各値をダブルクォーテーションで囲む
単純なCSVであれば、行頭・行末・カンマを順番に置換することで、各値をダブルクォーテーションで囲める。
例:aaaa,bbbb,cccc,dddd
→ "aaaa","bbbb","cccc","dddd"
以下の3ステップで処理する。
^→"(行頭にダブルクォーテーションを追加)$→"(行末にダブルクォーテーションを追加),→","(カンマをダブルクォーテーション付きカンマに置換)
値の中にカンマや改行が含まれるCSVでは、この方法だけでは正しく処理できない場合がある。その場合はCSV対応のエディタやプログラムで処理する方が安全だ。
CSV列の順序を入れ替える
カンマ区切りの列をキャプチャすると、列の順序を入れ替えられる。
例:aaaa,bbbb,cccc,dddd
→ bbbb,cccc,aaaa,dddd
| 検索 | 置換 |
|---|---|
^([^,]+),([^,]+),([^,]+),([^,]+)$ | $2,$3,$1,$4 |
([^,]+) でカンマ以外の文字の連続を1列分としてキャプチャし、$1 から $4 の順番を並び替えている。
リストを決まったコードの書式に変換する
項目数が多い表やテーブルのデータを、変数への代入文や定型コードへまとめて一括変換したい時にも正規表現が役立つ。手作業で1件ずつ追加するより、記述漏れや入力ミスを減らしやすい。
例:KARIBARAI,仮払申請計上仕訳
→ l_KARIBARAI = l_Sheet.Range("仮払申請計上仕訳").Value '仮払申請計上仕訳
| 検索 | 置換 |
|---|---|
^([^,]+),(.+)$ | l_$1 = l_Sheet.Range("$2").Value '$2 |
1列目を変数名の一部、2列目をシート上の範囲名として使う例だ。実際のコードへ使う前に、カンマを含む項目名がないか、空行が混ざっていないかを確認しておくとよい。
プログラムで入力チェックに使う正規表現
フォームの入力値を確認する時も、正規表現はよく使われる。ただし、正規表現だけで完全な検証ができるとは限らないため、必要に応じてプログラム側の処理と組み合わせる。
| 目的 | 正規表現 | 備考 |
|---|---|---|
| 数字のみ | ^[0-9]+$ | 桁数制限なし |
| 数字n桁固定 | ^[0-9]{4}$ | 例は4桁固定。{4} の数字を変える |
| 数字n桁以内 | ^[0-9]{1,8}$ | 例は1〜8桁。上限を {1,n} で指定 |
| 英数字のみ | ^[a-zA-Z0-9]+$ | 桁数制限なし |
| 英数字n桁以内 | ^[a-zA-Z0-9]{1,16}$ | 例は1〜16桁 |
| 英数字記号(パスワード用) | ^[a-zA-Z0-9!@#$%^&*\-_=+]{8,32}$ | 例は8〜32桁。使用可能記号は !@#$%^&*-_=+ |
| Shift-JISで表現できる文字のみ(簡易) | ^[\u0000-\u007E\u00A5\u203E\uFF01-\uFF9F\u3000-\u9FFF\uF900-\uFAFF\uFFE0-\uFFE6]+$ | 絵文字などShift-JIS外の文字の混入を簡易的に検出する。完全な判定には文字コード変換チェックが確実 |
| 日付形式(yyyy/MM/ddまたはyyyy-MM-dd) | ^[0-9]{4}[/\-][0-9]{2}[/\-][0-9]{2}$ | 日付として実在するかまでは判定しない |
| 郵便番号(xxx-xxxx) | ^[0-9]{3}-[0-9]{4}$ | 日本の郵便番号形式 |
| 電話番号(ハイフンあり) | ^0[0-9]{1,4}-[0-9]{1,4}-[0-9]{4}$ | 固定電話・携帯電話を広めに許可する簡易パターン |
入力チェックでは、「形式が合っているか」と「実際に有効か」を分けて考える必要がある。たとえば日付形式の正規表現にマッチしても、2024/99/99 のような存在しない日付を許してしまう場合がある。
正規表現でうまく検索・置換できない時の確認ポイント
正規表現が思った通りに動かない時は、パターン全体を疑う前に、よくある原因を順番に確認すると解決しやすい。
- 特殊文字をそのまま検索していないか確認する
.*が広すぎる範囲にマッチしていないか確認する^と$が行単位で動いているか確認する- キャプチャグループの番号がずれていないか確認する
- 使っているツールが先読み・後読み・
\dなどに対応しているか確認する
特に多いのは、ドットをそのまま検索したいのに . と書いてしまうケースだ。ドットは「任意の1文字」という意味になるため、ドット文字そのものを探すなら \. と書く必要がある。
正規表現を安全に使うための注意点
正規表現は便利だが、一括置換や入力チェックに使う時は過信しないことが大切だ。
まず、一括置換の前には検索結果を確認し、必要に応じてファイルのコピーを残す。正規表現は条件に合う文字列をまとめて処理できるため、パターンが広すぎると想定外の箇所まで書き換えてしまう。
次に、ツールや言語による記法の違いに注意する。サクラエディタではキャプチャグループの置換に $1 の形式を使う例が多いが、別の環境では \1 を使う場合がある。先読み・後読み、改行の扱い、\d や \s の対象範囲も環境によって差が出ることがある。
最後に、複雑な構造を無理に正規表現だけで処理しないことも重要だ。HTML、CSV、日付、メールアドレスなどは、簡易的な抽出や形式チェックには正規表現が使えるが、厳密な解析や検証には専用の仕組みを併用した方がよい。
まとめ
正規表現は、文字列のパターンを記号で表す書き方だ。基本構文を覚えると、検索、置換、抽出、入力チェックの作業を効率化できる。
最初は .、*、+、[]、()、^、$ など、よく使う記号から理解するとよい。実務では、正規表現チェッカーで小さく試し、マッチ範囲を確認してからテキストエディタで置換する流れが安全だ。
正規表現は万能ではないが、使いどころを押さえれば、手作業の修正やデータ整形を大きく減らせる。まずはこの記事の例を短いテキストで試し、検索・置換の感覚をつかむところから始めるとよい。
コメント