正規表現(Regular expressions)は文字列内を検索したり置換するための強力な方法です。
JavaScriptでは、正規表現は組み込みの RegExp
クラスのオブジェクトを使用して実装され、文字列と統合されています。
正規表現
正規表現(もしくは “regexp”, または単に “reg”) は パターン とオプションの フラグ で構成されています。
正規表現オブジェクトを生成するための2つの構文があります。
長い構文:
regexp = new RegExp("pattern", "flags");
…そして短い構文です。スラッシュ "/"
を使います:
regexp = /pattern/; // フラグなし
regexp = /pattern/gmi; // g, m と i のフラグあり(詳細は後ほど説明します)
スラッシュ /.../
は正規表現を作成していることを JavaScript に伝えます。文字列の引用符と同じ役割を果たします。
どちらの場合も、regexp
は組み込みの RegExp
クラスのインスタンスになります。
これらの構文の主な違いは、スラッシュ /.../
を使用するパターンは式が挿入できないことです(テンプレートリテラル ${...}
のような)。これは完全に静的です。
スラッシュは、コードを書くときに正規表現を知っているときに使われます。そして、これが最も一般的なケースです。 new RegExp
は動的に生成された文字列から “その場” で正規表現を作成する必要がある場合にしばしば使われます。例えば:
let tag = prompt("What tag do you want to find?", "h2");
let regexp = new RegExp(`<${tag}>`); // 上のプロンプトで "h2" と入力された場合は、/<h2>/ になります
フラグ
正規表現には検索に影響を与えるフラグを含む場合があります。
JavaScript には 6 つしかありません:
i
- このフラグを指定すると、検索は大文字小文字を区別しません:
A
とa
に違いはありません(下の例をみてください)。 g
- このフラグを指定すると、検索はすべての一致を探します。指定がない場合は – 最初の1つのみを探します(次のチャプターで使い方を見ていきます)。
m
- 複数行モードです(チャプター 記事 "regexp-multiline" が見つかりません で説明します)。
s
- “dotall” モードを有効にします。これにより、ドット
.
が改行文字\n
に一致できるようになります(チャプター 文字クラス で説明しています)。 u
- 完全なユニコードサポートを有効にします。このフラグはサロゲートペアの正しい処理を可能にします。より詳細についてはチャプター Unicode(ユニコード): フラグ "u" とクラス \p{...} を参照してください。
y
- スティッキーモード: テキストの正確な位置で検索します(チャプター スティッキーフラグ(sticky flag) "y", 指定位置での検索 で説明します)。
ここからの配色は次の通りです:
- 正規表現 –
red
- 文字列 (検索する場所) –
blue
- 結果 –
green
検索: str.match
前述のように、正規表現は文字列のメソッドと統合されています。
メソッド str.match(regexp)
は文字列 str
中のすべての regexp
の一致を見つけます。
3つの動作モードがあります:
-
正規表現にフラグ
g
がある場合、すべての一致の配列を返します:let str = "We will, we will rock you"; alert( str.match(/we/gi) ); // We,we (マッチする2つの部分文字列の配列)
We
とwe
の両方が見つかることに注目してください。フラグi
は正規表現が大文字小文字を区別しないようにします。 -
そのようなフラグがない場合は、配列の形式で最初に一致したものだけを返します。インデック
0
でマッチした内容があり、あといくつか詳細情報のためのプロパティを持っています:let str = "We will, we will rock you"; let result = str.match(/we/i); // g フラグなし alert( result[0] ); // We (最初の一致) alert( result.length ); // 1 // 詳細: alert( result.index ); // 0 (一致した位置) alert( result.input ); // We will, we will rock you (元の文字列)
正規表現の一部が括弧で囲まれている場合は、配列は
0
以外のインデックスを持っている場合があります。これについてはチャプター キャプチャグループ で説明します。 -
そして、最後に、一致するものがなかった場合は
null
が返却されます(フラグg
の有無は関係ありません)。ここに重要な違いがあります。一致するものがない場合、殻の配列を受け取るのではなく
null
を受け取ります。これを忘れるとエラーにつながる可能性があるので注意してください。例えば:let matches = "JavaScript".match(/HTML/); // = null if (!matches.length) { // Error: Cannot read property 'length' of null alert("Error in the line above"); }
結果を常に配列にしたい場合は次のようにします。:
let matches = "JavaScript".match(/HTML/) || []; if (!matches.length) { alert("No matches"); // 問題なく動きます }
置換: str.replace
メソッド str.replace(regexp, replacement)
は文字列 str
で regexp
を使用して見つけた一致を replacement
に置き換えます(フラグg
があればすべての一致を、そうでなければ最初の1つだけが対象になります)。
例:
// g フラグなし
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
// g フラグあり
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
2番目の引数は replacement
文字列です。特別な文字の組み合わせを使用して、一致した内容の部分を挿入することもできます。:
記号 | 置換文字列での動作 |
---|---|
$& |
一致したもの全体を挿入します |
$` |
一致の前の部分文字列を挿入します |
$' |
一致した後の部分文字列を挿入します |
$n |
n が1-2桁の数値の場合、n番目の括弧の内容を挿入します。詳細についてはチャプター キャプチャグループ で説明します |
$<name> |
指定された name の括弧の中身を挿入します。詳細についてはチャプター キャプチャグループ で説明します |
$$ |
文字 $ を挿入します |
$&
の例です:
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
テスト: regexp.test
メソッド regexp.test(str)
は、少なくとも1つの一致を検索し、見つかれば true
を、なければ false
を返します。
let str = "I love JavaScript";
let regexp = /LOVE/i;
alert( regexp.test(str) ); // true
このパートの後半では、より多くの正規表現を学び、より多くの例を見ていき、他のメソッドにも触れます。
メソッドに関する完全な情報は RegExp と文字列のメソッド にあります。
サマリ
- 正規表現はパターンとオプションのフラグで構成されます:
g
,i
,m
,u
,s
,y
. - フラグと特殊記号(後で学びます)がない場合、正規表現による検索は部分文字列検索と同じです。
- メソッド
str.match(regexp)
は一致を探します:g
フラグがあればすべてを、なければ最初の1つだけが対象です。 - メソッド
str.replace(regexp, replacement)
はregexp
を使用して見つけた一致をreplacement
に置換します:g
フラグがあればすべてを、なければ最初の1つだけが対象です。 - メソッド
regexp.test(str)
が少なくとも1つ一致があればtrue
を、なければfalse
を返します。