次の方法で共有


後方参照

正規表現の最も重要な機能の 1 つに、後で使用できるように、一致したパターンの一部を記憶しておく機能があります。前に説明したように、正規表現パターンの全体または一部をかっこで囲むと、その部分が一時バッファに格納されます。このサブ式の保存機能を無効にするには、メタキャラクタ ('?:'、'?='、または '?!') を使用します。

正規表現パターンの左から右に向かって一致検索が行われ、サブマッチは一致した順番に保存されます。サブマッチが保存されるバッファ番号は、1 から始まり、最大 99 までです。各バッファにアクセスするには '\n' を使用します。ここで n は、特定のバッファを識別する 1 桁または 2 桁の 10 進数を表します。

後方参照の最も簡単で便利な応用例として、テキスト内で、同じ単語が 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 アドレスのプロトコル部分を取り込みます。このサブ式は、1 つのコロンと 2 つのスラッシュより前にある任意の単語に一致します。2 番目は Web アドレスのドメイン アドレス部分を取り込みます。このサブ式は、'^'、'/'、':' の文字を含まない任意の文字の並びに一致します。3 番目は、Web サイトのポート番号が指定されている場合、その番号を取り込みます。このサブ式は、コロンに続く 0 個以上の数字に一致します。最後に、4 番目は Web アドレスに指定されたパス情報とページ情報の両方またはいずれかを取り込みます。このサブ式は、'#' およびスペース以外の 1 つまたは複数の文字に一致します。

この正規表現を上記の URI に適用すると、次のように、サブマッチに文字列が保存されます。

RegExp.$1 - "http"

RegExp.$2 - "msdn.microsoft.com"

RegExp.$3 - ":80"

RegExp.$4 - "/scripting/default.htm"