更新 : 2007 年 11 月
正規表現の最も重要な機能の 1 つに、一致したパターンの一部を後で使用できるように記憶しておくことがあります。前述したように、正規表現のパターンまたはパターンの一部をかっこで囲むと、かっこで囲んだ部分が一時バッファに保存されます。一致したパターンを記憶しないメタ文字の ?:、?=、または ?! を使用すると、記憶されたパターンを上書きできます。
前方参照の使用
記憶された各サブマッチは、正規表現パターンの左から右の順に保存されます。部分式が保存されるバッファ番号は 1 から始まり、最大 99 までです。各バッファにアクセスするには、\n を使用します。ここで、n はバッファを指定する 1 桁または 2 桁の数字です。
前方参照の最も簡単で便利な用途は、文字列内で隣接している 2 つの同じ単語の一致候補を特定することです。次に例を示します。
Is is the cost of of gasoline going up up?
上の文では、いくつかの単語が重複しています。単語を 1 つずつ調べていくことなく、このような文を修正できると便利です。次の正規表現では、これを実現するために 1 つの部分式を使用しています。
/\b([a-z]+) \1\b/gi
記憶されたサブマッチには、[a-z]+ で指定されているように、1 つ以上のアルファベットが含まれています。正規表現の 2 番目の部分は、その前に記憶されたサブマッチへの参照です。つまり、かっこ内の正規表現と一致した 2 つ目の一致候補です。\1 は、1 つ目のサブマッチを表します。単語の境界を表すメタ文字によって、単語だけが検出されます。メタ文字を指定しないと、正規表現によって "is issued" や "this is" なども間違って検出されてしまいます。
通常の正規表現に続けてグローバル フラグ (g) を指定して、入力文字列にある一致候補とできるだけ多く一致するようにします。正規表現の最後に i フラグを指定して、大文字小文字を区別しないようにします。複数行フラグは、改行文字の前後に一致候補が存在する場合があることを表します。
上に示した正規表現を使用すると、次のコードでサブマッチ情報を使用して、テキスト内にある 2 つの連続したまったく同じ単語が、同じ単語 1 つと置換されます。
var ss = "Is is the cost of of gasoline going up up?.\n";
var re = /\b([a-z]+) \1\b/gim; //Create regular expression pattern.
var rv = ss.replace(re,"$1"); //Replace two occurrences with one.
replace メソッドで $1 を使用しているのは、1 番目に保存されたサブマッチを参照するためです。サブマッチが複数ある場合は、続けて $2、$3 などを使用して参照します。
また、前方参照を使用して、URI (Universal Resource Indicator) をコンポーネントに分割できます。次の URI をプロトコル (ftp、http など)、ドメイン アドレス、およびページ/パスに分割するとします。
https://msdn.microsoft.com:80/scripting/default.htm
次の正規表現を使用して分割します。
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
1 番目のかっこの部分式で、Web アドレスのプロトコルの部分を取り出します。この部分式は、コロンと 2 つのスラッシュで始まる単語と一致します。2 番目のかっこの部分式は、アドレスのドメイン アドレスの部分を取り出します。この部分式は、/ または : 以外の、1 文字以上の文字と一致します。3 番目のかっこの部分式は、ポート番号が指定されている場合に、その番号を取り出します。この部分式は、コロンに続く 0 桁以上の数字と一致します。この部分式は、1 回だけ繰り返すことができます。4 番目のかっこの部分式は、Web アドレスで指定されたパスとページの情報を取り出します。この部分式は、# または空白文字を含まない文字の並びと一致します。
この正規表現を上に示した URI に適用すると、サブマッチは次のようになります。
RegExp.$1 には "http" が記憶されます。
RegExp.$2 には "msdn.microsoft.com" が記憶されます。
RegExp.$3 には ":80" が記憶されます。
RegExp.$4 には "/scripting/default.htm" が記憶されます。