「特定の単語やパターンを一瞬で見つけ出す方法はないだろうか?」
プログラミングやデータ処理をしていると、膨大なテキストの中から特定の文字列を探す必要が出てきます。手作業でチェックするのは現実的ではありません。
そんなときに威力を発揮するのが 正規表現(Regular Expression) です。
正規表現を使えば、単なるキーワード検索以上に柔軟なパターンマッチングが可能になります。
本記事では、正規表現を使って効率よく文字列をヒットさせる方法を、初心者にもわかりやすく解説します!
正規表現(Regular Expression)とは、文字列のパターンを指定して検索・抽出・置換を行うための機能の一部です。プログラミングやデータ処理において、特定の単語や形式に一致する文字列を効率よく見つけるために使われます。
例えば、次のような場面で活用できます。
手動で文字列をチェックするのは非効率ですが、正規表現を使えば 数行のコードで瞬時に処理 できます。
次の章では、正規表現の基本的な構文について詳しく解説します!
JavaScriptでは、正規表現を使うことで、文字列の検索や置換を効率的に行うことができます。
ここでは、基本的な構文をJavaScriptのコードとともに紹介します。
.
(ドット).
は「どんな1文字にもマッチ」する特殊記号です。
```jsconst pattern = /a.b/;
```
const text = "acb abb axb a12b";
const matches = text.match(pattern);
console.log(matches); // ['acb']
a.b
は「a と b の間に どんな1文字 でも入っているパターン」を探します。
変数 text
の中でヒットするのは、 ‘acb’の文字列だけです。
*
(アスタリスク)*
は「直前の文字やグループが 0回以上繰り返される」場合にマッチします。
```jsconst pattern = /ab*c/g;
```
const text = "ac abc abbc abbbc";
const matches = text.match(pattern);
console.log(matches); // ['ac', 'abc', 'abbc', 'abbbc']
b*
の部分が b が0回以上繰り返される ことを示しているため、”ac” もヒットします。
※ /○○/g; の g は グローバルフラグと呼ばれるものです。
ヒットしたすべての文字列という意味で、1つだけマッチすればいい場合はグローバルフラグはなしでOKです。すべてのマッチを取得・置換したい場合はグローバルフラグをつけましょう。
+
(プラス)+
は「直前の文字が 1回以上 連続する場合」にマッチします。
```jsconst pattern = /ab+c/g;
```
const text = "ac abc abbc abbbc";
const matches = text.match(pattern);
console.log(matches); // ['abc', 'abbc', 'abbbc']
b+
は b が1回以上必要 なため、”ac” はマッチしません。
?
(クエスチョンマーク)?
は「直前の文字が 0回または1回だけ 出現する場合」にマッチします。
```jsconst pattern = /colou?r/g;
```
const text = "color colour colouur";
const matches = text.match(pattern);
console.log(matches); // ['color', 'colour']
u?
の部分は「u が あってもなくてもOK」という意味です。
[]
(角カッコ)[]
内に指定した文字の どれか1つ にマッチします。
```jsconst pattern = /gr[ae]y/g;
```
const text = "gray grey gruy";
const matches = text.match(pattern);
console.log(matches); // ['gray', 'grey']
[ae]
の部分が「a または e」を意味し、”gray” と “grey” の両方にマッチします。
{}
(波カッコ){}
を使うと 繰り返し回数を指定 できます。
```jsconst pattern = /\d{3}-\d{4}/g;
```
const text = "123-4567 12-345 1234-567";
const matches = text.match(pattern);
console.log(matches); // ['123-4567']
\d{3}-\d{4}
は「数字3桁 + -
+ 数字4桁」にマッチします。
※\dは何かしらの数字を表します。
ここでは JavaScript の正規表現を使って文字列をヒットさせる方法を実際のコードで解説します。
```js
const text = "連絡先: test@example.com, backup: user123@mail.co.jp";
const pattern = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
const matches = text.match(pattern);
console.log(matches); // ['test@example.com', 'user123@mail.co.jp']
```
```js
const text = "固定電話: 03-1234-5678, 携帯電話: 090-9876-5432";
const pattern = /\d{2,4}-\d{3,4}-\d{4}/g;
const matches = text.match(pattern);
console.log(matches); // ['03-1234-5678', '090-9876-5432']
```
```js
const text = "2024-03-28はイベントの日です。2023-13-40は無効な日付。";
const pattern = /\b\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])\b/g;
const matches = text.match(pattern);
console.log(matches); // ['2024-03-28']
```
正規表現は強力ですが、初心者から上級者まで ミスしやすいポイント があります。
この章では、 ありがちなミスとその対策 を紹介します。
g
フラグの使い忘れ(JavaScript)```jsconst text = "apple, banana, apple, grape";
```
const pattern = /apple/;
const matches = text.match(pattern);
console.log(matches); // ['apple'] (最初の1つだけ)
g
(グローバル)フラグをつけないと、 最初の1つしか取得されない。
```jsconst pattern = /apple/g; // `g` を追加
```
const matches = text.match(pattern);
console.log(matches); // ['apple', 'apple']
.match()
で すべての一致を取得したい場合は g
フラグをつける!
.
(ドット)の誤用(「何でもマッチ」の落とし穴)```jsconst pattern = /a.b/;
```
const text = "axb a_b a1b";
const matches = text.match(pattern);
console.log(matches); // ['axb', 'a1b']
.
は 「どんな1文字にもマッチ」するため、予期しない文字にもヒット してしまう。
「a と b の間が特定の文字(例: _
)の場合のみヒットさせたい」ときは、 明示的に指定する。
```jsconst pattern = /a_b/;
```
const matches = text.match(pattern);
console.log(matches); // ['a_b']
.
は「何でもマッチ」するので、 不要なマッチを防ぐために慎重に使う!
\d
と [0-9]
の混同```jsconst pattern = /[0-9]/;
```
const text = "電話番号: 012-3456-7890";
const matches = text.match(pattern);
console.log(matches); // ['0'] (最初の1文字だけ)
[0-9]
は 1文字ずつ取得 してしまうため、完全な電話番号が取れない。
```js
const pattern = /\d{2,4}-\d{3,4}-\d{4}/g; // `\d` を使い、桁数を指定
const matches = text.match(pattern);
console.log(matches); // ['012-3456-7890']
```
1桁ずつ取得したくない場合 は、\d+
や {}
を使う。[0-9]
でも動作するが、\d
の方が 簡潔で可読性が高い。
^
(行頭)と $
(行末)の誤解```jsconst pattern = /^hello/;
```
const text = "Say hello to the world!";
console.log(text.match(pattern)); // null
^hello
は 「文字列の先頭が hello
」の場合のみ マッチするため、"hello"
が途中にある場合はヒットしない。
「途中に hello
があるかどうか」を調べたい場合
```jsconst pattern = /hello/;
```
console.log(text.match(pattern)); // ['hello']
「完全に hello
だけの行をマッチさせたい場合」
```jsconst pattern = /^hello$/;
```
const text1 = "hello";
const text2 = "hello world";
console.log(text1.match(pattern)); // ['hello']
console.log(text2.match(pattern)); // null
^
と $
は 文字列の先頭・末尾に限定したいときに使う。
部分一致なら ^
や $
を使わない。
\b
(単語境界)の使い方ミス```jsconst pattern = /car/;
```
const text = "carpet cartoon car";
const matches = text.match(pattern);
console.log(matches); // ['car', 'car'] ('carpet' もヒットしてしまう)
"carpet"
や "cartoon"
の 中にも car
が含まれる ため、意図しないマッチが発生。
```jsconst pattern = /\bcar\b/;
```
const matches = text.match(pattern);
console.log(matches); // ['car']
単語そのものを探す場合は \b
(単語境界)をつける!\b
は「単語の前後が 空白や記号、文の境界」であることをチェックする。
test()
の使い方ミス(JavaScript)```jsconst pattern = /hello/g;
```
const text = "hello hello hello";
console.log(pattern.test(text)); // true
console.log(pattern.test(text)); // false(!?)
console.log(pattern.test(text)); // true
g
フラグをつけた test()
は、呼び出すたびに次のマッチを探す ため、2回目は false
になってしまう。
test()
には g
フラグを つけない!
```jsconst pattern = /hello/; // `g` を外す
```
console.log(pattern.test(text)); // true
console.log(pattern.test(text)); // true(何度呼んでも同じ結果)
test()
で 単純なマッチチェックをしたいなら g
フラグは不要!
すべてのマッチを取得したいなら .match()
を使う。
replace()
で置換漏れ(JavaScript)```jsconst text = "apple banana apple";
```
const result = text.replace(/apple/, "orange");
console.log(result); // "orange banana apple"(最初の `apple` だけ置換)
replace()
は デフォルトで最初の1つしか置換しない。
```jsconst result = text.replace(/apple/g, "orange");
```
console.log(result); // "orange banana orange"
すべての一致を置換したい場合は g
フラグをつける!replaceAll()
でも可能(ES2021以降)
ミス | 対策 |
---|---|
g フラグなしで .match() する | g をつける |
. の誤用 | 具体的な文字を指定 |
[0-9] で1桁ずつ取得 | \d+ を使う |
^ や $ の誤解 | 部分一致なら使わない |
\b なしで単語検索 | \b をつける |
test() に g 付き | g を外す |
replace() で1つしか置換されない | g をつける |
正規表現の 基本 を理解したら、次は 応用的なテクニック を学びましょう。
ここでは グループ化・先読み・後読み などの 高度な活用法 を紹介します。
()
(キャプチャグループ)複数の部分をまとめて扱いたい場合 に使います。
```jsconst text = "2024/03/28 2025/12/01";
```
const pattern = /(\d{4})\/(\d{2})\/(\d{2})/g;
const result = text.replace(pattern, "$1-$2-$3");
console.log(result); // "2024-03-28 2025-12-01"
解説:
(\d{4})
→ キャプチャグループ1(年)(\d{2})
→ キャプチャグループ2(月)(\d{2})
→ キャプチャグループ3(日)"$1-$2-$3"
で /
を -
に変換match()
で グループごとに取得 することも可能!
```jsconst match = text.match(pattern);
```
console.log(match); // ['2024/03/28', '2025/12/01']
(?:...)
(グループ化するが保存しない)通常の ()
は キャプチャ されますが、 不要な場合は (?:...)
を使う ことで、無駄なメモリ使用を防げます。
```jsconst text = "Mr. Smith, Mrs. Johnson, Miss Brown";
```
const pattern = /(?:Mr|Mrs|Miss)\. (\w+)/g;
const matches = [...text.matchAll(pattern)];
console.log(matches.map(m => m[1])); // ['Smith', 'Johnson', 'Brown']
解説:
(?:Mr|Mrs|Miss)
→ 「Mr」「Mrs」「Miss」のどれかに一致(キャプチャしない)(\w+)
→ 名前部分をキャプチャ(?:...)
を使うと、グループの番号を無駄に消費せず、可読性が向上!
(?=...)
(条件を満たす場合のみマッチ)マッチ対象を決めるが、実際のマッチには含めない 方法です。
```jsconst text = "価格: $100, 200円, $300, ¥400";
```
const pattern = /\$\d+(?=[^\d]|$)/g;
const matches = text.match(pattern);
console.log(matches); // ['$100', '$300']
解説:
\$\d+
→ $
に続く数字 を取得(?=[^\d]|$)
→ 数字の後が「数字以外」or「文末」の場合のみマッチ $100,
は ,
の前で止まる$300
は文末なのでマッチ「特定の文字が後に続く場合のみ」マッチさせるときに便利!
(?!...)
(特定の条件を満たさない場合のみマッチ)「あるパターンが後ろに続かない場合のみ」マッチ させる方法です。
```jsconst text = "apple apples";
```
const pattern = /apple(?!s)/g;
const matches = text.match(pattern);
console.log(matches); // ['apple']
解説:
apple(?!s)
→ 「s が続かない apple のみ」マッチ"apples"
には s
があるので マッチしない否定先読みを使えば「完全一致に近い」検索が可能!
(?<=...)
(特定の条件の後にある文字を取得)「あるパターンの後に続くもの」だけを取得したいとき に使います。
```jsconst text = "100円, 200 dollars, 300円";
```
const pattern = /(?<=\d)円/g;
const matches = text.match(pattern);
console.log(matches); // ['円', '円']
解説: (?<=\d)円
→ 「数字の後に 円
がある場合のみ」マッチ
「特定の文字の後に続くものを取得」したいときに便利!
JavaScript では ES2018 以降で後読みが使用可能!
(?<!...)
(特定のパターンの後に続かない場合のみマッチ)「特定の文字の後に続かないものだけ取得」する 方法です。
```jsconst text = "¥100, $100, ¥200, $200";
```
const pattern = /(?<!\$)\d+/g;
const matches = text.match(pattern);
console.log(matches); // ['100', '200']
解説:
(?<!\$)\d+
→ 「$
が直前にない数字のみ」マッチ$100
や $200
はスキップされる否定後読みを使うと「特定の条件を満たさない場合のみマッチ」が可能!
matchAll()
ですべてのマッチとキャプチャを取得(JavaScript)match()
では 単にマッチした単語を取得 しますが、matchAll()
を使うと 「キャプチャグループごとに取得」 できます!
```jsconst text = "<h1>Title</h1> <p>Hello</p>";
```
const pattern = /<(\w+)>(.*?)<\/\1>/g;
const matches = [...text.matchAll(pattern)];
console.log(matches.map(m => ({ tag: m[1], content: m[2] })));
/*
[
{ tag: 'h1', content: 'Title' },
{ tag: 'p', content: 'Hello' }
]
*/
解説:
<(\w+)>
→ 開始タグを取得(h1, p など)(.*?)
→ タグ内のテキストを取得<\/\1>
→ 同じタグ名で閉じているか確認matchAll()
を使うと「詳細な情報を配列で取得」できる!
テクニック | 用途 |
---|---|
() (キャプチャグループ) | 部分一致の抽出・置換 |
(?:...) (非キャプチャ) | グループ化するが保存しない |
(?=...) (先読み) | 「後ろに続くものを条件」にする |
(?!...) (否定先読み) | 「後ろに続かない場合のみ」マッチ |
(?<=...) (後読み) | 「特定の文字の後にあるもの」を取得 |
(?<!...) (否定後読み) | 「特定の文字の後にないもの」を取得 |
matchAll() | すべてのマッチとキャプチャ情報を取得 |
これらの応用テクニックを使えば、正規表現を さらに強力なツール にできます!
正規表現は、単純な検索・置換だけでなく、高度なテキスト処理やデータ抽出 にも活用できる強力なツールです。
本記事では、基本から応用まで 幅広い正規表現のテクニックを紹介しました。
正規表現を使いこなせば、データ処理や検索作業が 劇的にスピードアップ します。
ぜひ実際のコーディングで活用してみましょう!
This website uses cookies.