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