Categories: ITコラム

正規表現を使って文字列をヒットする方法 | JavaScript

「特定の単語やパターンを一瞬で見つけ出す方法はないだろうか?」

プログラミングやデータ処理をしていると、膨大なテキストの中から特定の文字列を探す必要が出てきます。手作業でチェックするのは現実的ではありません。

そんなときに威力を発揮するのが 正規表現(Regular Expression) です。

正規表現を使えば、単なるキーワード検索以上に柔軟なパターンマッチングが可能になります。

本記事では、正規表現を使って効率よく文字列をヒットさせる方法を、初心者にもわかりやすく解説します!

スポンサーリンク

正規表現とは?

正規表現(Regular Expression)とは、文字列のパターンを指定して検索・抽出・置換を行うための機能の一部です。プログラミングやデータ処理において、特定の単語や形式に一致する文字列を効率よく見つけるために使われます。

例えば、次のような場面で活用できます。

  • メールアドレスの抽出(例:example@mail.com など)
  • 電話番号のフォーマットチェック(例:03-1234-5678 など)
  • 特定のキーワードを含む文章の検索
  • 文章内の日付を見つけて別の形式に変換

手動で文字列をチェックするのは非効率ですが、正規表現を使えば 数行のコードで瞬時に処理 できます。

次の章では、正規表現の基本的な構文について詳しく解説します!

正規表現で文字列をヒットさせる基本構文

JavaScriptでは、正規表現を使うことで、文字列の検索や置換を効率的に行うことができます。

ここでは、基本的な構文をJavaScriptのコードとともに紹介します。

1. 任意の1文字にマッチする .(ドット)

. は「どんな1文字にもマッチ」する特殊記号です。

```js
const 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’の文字列だけです。


2. 0回以上の繰り返しを表す *(アスタリスク)

* は「直前の文字やグループが 0回以上繰り返される」場合にマッチします。

```js
const 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です。すべてのマッチを取得・置換したい場合はグローバルフラグをつけましょう。

3. 1回以上の繰り返しを表す +(プラス)

+ は「直前の文字が 1回以上 連続する場合」にマッチします。

```js
const 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” はマッチしません。


4. 0回または1回の出現を表す ?(クエスチョンマーク)

? は「直前の文字が 0回または1回だけ 出現する場合」にマッチします。

```js
const pattern = /colou?r/g;
const text = "color colour colouur";
const matches = text.match(pattern);
console.log(matches); // ['color', 'colour']
```

u? の部分は「u が あってもなくてもOK」という意味です。


5. いずれかの文字にマッチする [](角カッコ)

[] 内に指定した文字の どれか1つ にマッチします。

```js
const 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” の両方にマッチします。


6. 指定した回数だけ繰り返す {}(波カッコ)

{} を使うと 繰り返し回数を指定 できます。

```js
const 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)

間違い

```js
const text = "apple, banana, apple, grape";
const pattern = /apple/;
const matches = text.match(pattern);
console.log(matches); // ['apple'] (最初の1つだけ)
```

g(グローバル)フラグをつけないと、 最初の1つしか取得されない

対策

```js
const pattern = /apple/g; // `g` を追加
const matches = text.match(pattern);
console.log(matches); // ['apple', 'apple']
```

.match()すべての一致を取得したい場合は g フラグをつける

.(ドット)の誤用(「何でもマッチ」の落とし穴)

間違い

```js
const pattern = /a.b/;
const text = "axb a_b a1b";
const matches = text.match(pattern);
console.log(matches); // ['axb', 'a1b']
```

.「どんな1文字にもマッチ」するため、予期しない文字にもヒット してしまう。

対策

「a と b の間が特定の文字(例: _)の場合のみヒットさせたい」ときは、 明示的に指定する

```js
const pattern = /a_b/;
const matches = text.match(pattern);
console.log(matches); // ['a_b']
```

. は「何でもマッチ」するので、 不要なマッチを防ぐために慎重に使う

\d[0-9] の混同

間違い

```js
const 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 の方が 簡潔で可読性が高い

^(行頭)と $(行末)の誤解

間違い

```js
const pattern = /^hello/;
const text = "Say hello to the world!";
console.log(text.match(pattern)); // null
```

^hello「文字列の先頭が hello」の場合のみ マッチするため、"hello" が途中にある場合はヒットしない。

対策

「途中に hello があるかどうか」を調べたい場合

```js
const pattern = /hello/;
console.log(text.match(pattern)); // ['hello']
```

「完全に hello だけの行をマッチさせたい場合」

```js
const pattern = /^hello$/;
const text1 = "hello";
const text2 = "hello world";

console.log(text1.match(pattern)); // ['hello']
console.log(text2.match(pattern)); // null
```

^$文字列の先頭・末尾に限定したいときに使う
部分一致なら ^$ を使わない。

\b(単語境界)の使い方ミス

間違い

```js
const pattern = /car/;
const text = "carpet cartoon car";
const matches = text.match(pattern);
console.log(matches); // ['car', 'car'] ('carpet' もヒットしてしまう)
```

"carpet""cartoon"中にも car が含まれる ため、意図しないマッチが発生。

対策

```js
const pattern = /\bcar\b/;
const matches = text.match(pattern);
console.log(matches); // ['car']
```

単語そのものを探す場合は \b(単語境界)をつける!
\b は「単語の前後が 空白や記号、文の境界」であることをチェックする。

test() の使い方ミス(JavaScript)

間違い

```js
const 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 フラグを つけない

```js
const pattern = /hello/; // `g` を外す
console.log(pattern.test(text)); // true
console.log(pattern.test(text)); // true(何度呼んでも同じ結果)
```

test()単純なマッチチェックをしたいなら g フラグは不要
すべてのマッチを取得したいなら .match() を使う。

replace() で置換漏れ(JavaScript)

間違い

```js
const text = "apple banana apple";
const result = text.replace(/apple/, "orange");
console.log(result); // "orange banana apple"(最初の `apple` だけ置換)
```

replace()デフォルトで最初の1つしか置換しない

対策

```js
const 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 をつける

応用編:高度な正規表現の活用テクニック

正規表現の 基本 を理解したら、次は 応用的なテクニック を学びましょう。
ここでは グループ化・先読み・後読み などの 高度な活用法 を紹介します。

① グループ化 ()(キャプチャグループ)

複数の部分をまとめて扱いたい場合 に使います。

例:日付のフォーマットを統一する(YYYY/MM/DD → YYYY-MM-DD)

```js
const 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()グループごとに取得 することも可能!

```js
const match = text.match(pattern);
console.log(match); // ['2024/03/28', '2025/12/01']
```

② 非キャプチャグループ (?:...)(グループ化するが保存しない)

通常の ()キャプチャ されますが、 不要な場合は (?:...) を使う ことで、無駄なメモリ使用を防げます。

例:「Mr.」「Mrs.」「Miss」を含む名前を抽出

```js
const 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+)名前部分をキャプチャ

(?:...) を使うと、グループの番号を無駄に消費せず、可読性が向上!

③ 先読み (?=...)(条件を満たす場合のみマッチ)

マッチ対象を決めるが、実際のマッチには含めない 方法です。

✅ 例:「$」がつく価格のみ抽出

```js
const 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 は文末なのでマッチ

「特定の文字が後に続く場合のみ」マッチさせるときに便利!

④ 否定先読み (?!...)(特定の条件を満たさない場合のみマッチ)

「あるパターンが後ろに続かない場合のみ」マッチ させる方法です。

✅ 例:「apple」だけを含み、「apples」にはマッチさせない

```js
const text = "apple apples";
const pattern = /apple(?!s)/g;

const matches = text.match(pattern);
console.log(matches); // ['apple']
```

解説:

  • apple(?!s)「s が続かない apple のみ」マッチ
  • "apples" には s があるので マッチしない

否定先読みを使えば「完全一致に近い」検索が可能!

⑤ 後読み (?<=...)(特定の条件の後にある文字を取得)

「あるパターンの後に続くもの」だけを取得したいとき に使います。

✅ 例:「円」という単位の前にある金額だけ取得

```js
const text = "100円, 200 dollars, 300円";
const pattern = /(?<=\d)円/g;

const matches = text.match(pattern);
console.log(matches); // ['円', '円']
```

解説: (?<=\d)円「数字の後に がある場合のみ」マッチ

「特定の文字の後に続くものを取得」したいときに便利!
JavaScript では ES2018 以降で後読みが使用可能!

⑥ 否定後読み (?<!...)(特定のパターンの後に続かない場合のみマッチ)

「特定の文字の後に続かないものだけ取得」する 方法です。

✅ 例:「¥100」は取得するが、「$100」は無視

```js
const 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() を使うと 「キャプチャグループごとに取得」 できます!

例:HTML タグからコンテンツを取得

```js
const 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()すべてのマッチとキャプチャ情報を取得

これらの応用テクニックを使えば、正規表現を さらに強力なツール にできます!

正規表現を使いこなして検索を効率化しよう!

正規表現は、単純な検索・置換だけでなく、高度なテキスト処理やデータ抽出 にも活用できる強力なツールです。

本記事では、基本から応用まで 幅広い正規表現のテクニックを紹介しました。

  • 「単純な検索」から「高度なデータ抽出」まで、正規表現を活用しよう!
  • ミスを防ぐコツを押さえれば、強力な武器に!
  • 適切なテクニックを組み合わせて、検索・置換を効率化!

正規表現を使いこなせば、データ処理や検索作業が 劇的にスピードアップ します。
ぜひ実際のコーディングで活用してみましょう!

情シスマン

情報システム部の担当として知見を深めた内容を発信していきます。

Recent Posts

【JSTQB】3章 静的テスト|解説

(※当記事は、2024年12月…

4か月 ago

【JSTQB】1章 テストの基礎|解説

(※当記事は、2024年12月…

4か月 ago

Gitとは?利便性や用途について深掘りして解説

エンジニアとしてプログラミング…

5か月 ago

This website uses cookies.