JavaScript 正規表現で特殊文字を制圧! エスケープシーケンスマスターへの道
本記事では、JavaScript 正規表現におけるエスケープシーケンスについて、わかりやすく詳細に解説します。
エスケープシーケンスは、バックスラッシュ (\
) とそれに続く文字で構成される一連の記号です。これらの記号は、正規表現エンジンに対して、その後に続く文字を特殊な意味ではなく、通常の文字として解釈するように指示します。
例:
\n
:改行を表す\\
:バックスラッシュそのものを表す
エスケープが必要な文字
以下の文字は、JavaScript 正規表現において特殊な意味を持つため、エスケープする必要があります。
.
(ピリオド):任意の1文字を表す*
(アスタリスク):0回以上繰り返される任意の文字列を表す?
(クエスチョンマーク):0回または1回出現する任意の文字列を表す^
(キャレット):行の先頭を表す$
(ドル記号):行の末尾を表す[]
(角括弧):文字クラスを表す()
(円括弧):グループを表す\{\}
(波括弧):量子化を表す/
(スラッシュ):正規表現リテラルの境界を示す
"abc123"
という文字列から、数字を含む部分のみを抽出したい場合、以下の正規表現を使用できます。
/a.*c\d+/
しかし、この正規表現は "abc123"
全体とマッチしてしまいます。これは、.
が任意の1文字を表す特殊な意味を持つためです。
この問題を解決するには、.
をエスケープする必要があります。
/a.*c\\d+/
上記のように、.
を \\
でエスケープすることで、.
は単なるピリオドとして解釈され、期待通りの結果が得られます。
その他のエスケープシーケンス
上記以外にも、JavaScript 正規表現で使用できるエスケープシーケンスがいくつかあります。
\b
:単語の境界を表す\f
:フォームフィードを表す\xHH
:16進数コードで指定した文字を表す (例:\x41
は "A" を表す)
これらのエスケープシーケンスは、より複雑な正規表現パターンを作成する際に役立ちます。
正規表現リテラルと RegExp コンストラクタ
JavaScript における正規表現リテラルは、スラッシュ (/
) で囲まれた文字列で記述されます。一方、RegExp コンストラクタを使用して、正規表現オブジェクトを作成することもできます。
RegExp コンストラクタを使用する場合、エスケープシーケンスを二重にする必要があります。これは、バックスラッシュ (\
) が、正規表現リテラルの境界を示す特殊な意味を持つためです。
// 正規表現リテラル
const regex1 = /a.*c\d+/;
// RegExp コンストラクタ
const regex2 = new RegExp('a.*c\\d+');
上記のように、RegExp コンストラクタを使用する場合は、.
を \\
でエスケープする必要があります。
JavaScript 正規表現におけるエスケープシーケンスは、特殊文字をただの文字として扱い、予期しない動作を防ぐために重要な役割を果たします。本記事で解説した内容を理解することで、より複雑で強力な正規表現パターンを作成することが可能になります。
リファレンス
- [正規表現でエスケープが必要な文字を
JavaScript 正規表現におけるエスケープ - サンプルコード
文字列から数字のみを抽出
以下のコードは、"abc123def456" という文字列から数字のみを抽出する正規表現を示しています。
const str = "abc123def456";
const regex = /\d+/;
const matches = str.match(regex);
console.log(matches); // 結果: ["123", "456"]
このコードでは、\d+
という正規表現を使用しています。これは、1回以上繰り返される数字を表します。
しかし、この正規表現は "123abc456" のような文字列の場合、数字と英字が混ざった結果を返してしまいます。
const str = "123abc456";
const regex = /\d+/;
const matches = str.match(regex);
console.log(matches); // 結果: ["123", "456"]
これは、.
が任意の1文字を表す特殊な意味を持つためです。
const str = "123abc456";
const regex = /\d+/;
const matches = str.match(regex);
console.log(matches); // 結果: []
const str = "123abc456";
const regex = /\d+\b/; // \b で単語の境界を指定
const matches = str.match(regex);
console.log(matches); // 結果: ["123", "456"]
特殊文字を含む文字列を検索
以下のコードは、特殊文字を含む文字列を検索する正規表現を示しています。
const str = "*This is a special string*";
const regex = /\*.*\*/;
const matches = str.match(regex);
console.log(matches); // 結果: ["*This is a special string*"]
このコードでは、\*.*\**
という正規表現を使用しています。これは、アスタリスク (\*
) で始まり、任意の文字列 (.*
) を含み、アスタリスク (\*
) で終わる文字列を表します。
しかし、この正規表現は "*" のような単純な文字列にもマッチしてしまいます。
const str = "*This is a special string*";
const regex = /\*\\.*\*/;
const matches = str.match(regex);
console.log(matches); // 結果: ["*This is a special string*"]
Unicode 文字を検索
const str = "Hello, 世界";
const regex = /世/;
const matches = str.match(regex);
console.log(matches); // 結果: ["世"]
この問題を解決するには、Unicode コードポイントを使用して、"世" という漢字を指定する必要があります。
const str = "Hello, 世界";
const regex = /\u4E16/; // "世" のUnicode コードポイント
const matches = str.match(regex);
console.log(matches); // 結果: ["世"]
上記のように、\uXXXX
というエスケープシーケンスを使用して、Unicode コードポイントを指定することで、特定の Unicode 文字のみを検索することができます。
本記事で紹介したサンプルコードは、JavaScript 正規表現におけるエスケープの重要性を理解するためのほんの一例です。
より複雑な正規表現パターンを作成する際には、適切なエスケープシーケンスを使用することが重要になります。
上記で説明した内容を参考に、状況に応じて適切なエスケープシーケンスを選択し、より効果的な正規表現を作成してください。
JavaScript 正規表現におけるエスケープ - その他の方法
従来のバックスラッシュ (\
) を用いたエスケープシーケンスに加え、JavaScript には、より高度なエスケープを行うためのいくつかの方法が用意されています。
文字クラスは、特定の文字のグループを表現するための記号です。以下の表に、一般的な文字クラスとその使用方法を示します。
文字クラス | 説明 | 例 |
---|---|---|
[a-z] | 小文字の英字 | "abc" |
[A-Z] | 大文字の英字 | "ABC" |
[0-9] | 数字 | "123" |
[^a-zA-Z] | 英字ではない文字 | "!@#$%^&*" |
\w | 英数字またはアンダースコア | "hello_world" |
\s | 空白文字 | " \t\n\r" |
\S | 空白文字ではない文字 | "abc123" |
上記以外にも、より複雑な条件を指定できる文字クラスがあります。詳細は、JavaScript 正規表現リファレンス を参照してください。
正規表現フラグは、正規表現エンジンの動作を制御するためのオプションです。以下の表に、一般的な正規表現フラグとその効果を示します。
フラグ | 説明 | 例 |
---|---|---|
g | グローバルマッチ (すべての出現箇所を検索) | "abc123abc456".match(/ab/g) -> ["ab", "ab"] |
i | 大小文字を区別しない | "abc123".match(/ABC/i) -> ["ABC"] |
m | 多行マッチ (改行を含めて検索) | "abc\ndef\nghi".match(/^abc/m) -> ["abc"] |
s | ドットマッチ (改行を含むすべての文字をマッチ) | "abc\ndef\nghi".match(/./s) -> ["a", "b", "c", "\n", "d", "e", "f", "\n", "g", "h", "i"] |
y | 行アンカーの非貪欲マッチ (行の最初の位置からできるだけ短い部分にマッチ) | "abc123\nabc456".match(/^abc/y) -> ["abc"] |
正規表現フラグは、正規表現リテラルの末尾にスラッシュ (/
) で区切って指定します。
const regex = /abc/gi; // 大小文字を区別せず、すべての出現箇所を検索
RegExp クラスは、正規表現オブジェクトを作成するためのクラスです。このクラスを使用すると、エスケープシーケンスを二重にすることなく、正規表現リテラルと同じように正規表現を定義することができます。
const regex = new RegExp('a.*c\\d+', 'gi');
const str = "abc123def456";
const matches = str.match(regex);
console.log(matches); // 結果: ["abc123", "456"]
上記のように、RegExp クラスを使用すると、エスケープシーケンスをより簡潔に記述することができます。
これらの機能を効果的に活用することで、より複雑で表現力豊かな正規表現を作成することが可能になります。
状況に応じて適切な方法を選択し、より洗練された正規表現を使いこなしてください。
javascript regex escaping