Share via


代替とグループ化

代替では、'|' 文字を使って複数の選択肢の中から選択するように表現できます。章見出しの正規表現を拡張することにより、章見出し以外の見出しも処理対象とするように機能を拡張できます。ただし、この拡張は想像するほど簡単ではありません。代替を使用すると、'|' 文字の両側にある表現のうち、より広範囲に一致する表現が文字列に一致します。たとえば、次のような表現 (JScript および VBScript) では、行の先頭および末尾にある文字列で、'Chapter' または 'Section' の後に 1 桁または 2 桁の数字が続く文字列に一致するように見えます。

/^Chapter|Section [1-9][0-9]{0,1}$/
"^Chapter|Section [1-9][0-9]{0,1}$"

ところが、実際には、上記の正規表現は、行の先頭にある単語 'Chapter'、または行の末尾にあり数字が後に続く 'Section' という形式の文字列に一致します。入力文字列が 'Chapter 22' であっても、上の表現は単語 'Chapter' にしか一致しません。入力文字列が 'Section 22' であると 'Section 22' に一致しますが、これは意図する処理ではありません。目的に合った正規表現を作成する必要があります。次に、その方法を説明します。

その方法とは、かっこを使って代替の適用範囲を制限する方法です。つまり、代替が、'Chapter' と 'Section' の 2 つの単語だけに適用されるように指定できます。ただし、かっこはサブ式の作成にも使用するため、かっこの使用には注意が必要です。これについては、後のサブ式に関するトピックで説明します。上記の正規表現に対して、適切な位置にかっこを追加すると、正規表現が 'Chapter 1' または 'Section 3' のいずれにも一致するようになります。

次の正規表現は、かっこを使って 'Chapter' と 'Section' をグループ化することにより、正しく動作するように修正を加えたものです。JScript の場合は、次のようになります。

/^(Chapter|Section) [1-9][0-9]{0,1}$/

VBScript の場合は、次のようになります。

"^(Chapter|Section) [1-9][0-9]{0,1}$"

これらの表現を使用すると、一致処理は正しく行われますが、1 つの興味深い、付随して発生する動作があることに注意してください。かっこで 'Chapter|Section' を囲むと適切なグループ化を行うことができますが、後で使用できるように、2 つの単語のうち、一致した単語が記憶されることになります。上記の表現ではかっこが一組しか存在しないため、記憶される "サブマッチ" も 1 つだけになります。記憶されたサブマッチを参照するには、Submatches コレクション (VBScript の場合) または RegExp オブジェクトの $1 ~ $9 の各プロパティ (JScript の場合) を使用します。

サブマッチの記憶は、常に望ましいとは限りません。上記の例では、かっこを使って 'Chapter' と 'Section' の選択をグループ化することを目的としています。一致した部分文字列を後で参照するわけではありません。サブマッチを記憶する必要がない場合は、記憶しないようにします。こうすると、サブマッチを保存するための時間とメモリを節約でき、正規表現の処理性能を向上させることができます。

サブマッチを記憶しないようにするには、かっこ内の正規表現パターンの先頭に '?:' を付加します。上記の例について考えてみると、JScript の場合は、次のようになります。

/^(?:Chapter|Section) [1-9][0-9]{0,1}$/

VBScript の場合は、次のようになります。

"^(?:Chapter|Section) [1-9][0-9]{0,1}$"

'?:' メタキャラクタのほかにも、保存なしのメタキャラクタが 2 つあり、これらは、"先読み" 一致のために使用されます。'?=' を指定する肯定先読みは、かっこ内で一致正規表現が開始するところで検索文字列を一致させます。'?!' を指定する否定先読みは、かっこ内において、正規表現パターンに一致しない文字列の先頭位置で、検索文字列を一致させます。

たとえば、Windows 3.1、Windows 95、Windows 98、および Windows NT への参照を含むドキュメントがある場合を考えてみます。このとき、ドキュメント内の Windows 95、Windows 98、Windows NT への参照をすべて検索し、Windows 2000 への参照に置換する必要があるとします。このような場合には、次のような JScript 正規表現を使用できます。これは、Windows 95、Windows 98、および Windows NT に一致する肯定先読みの例です。

/Windows(?=95 |98 |NT )/

VBScript の場合は、次のようになります。

"Windows(?=95 |98 |NT )"

一致文字列が見つかると、先読みに含まれる文字が除外され、一致文字列の直後から、次の検索が開始されます。たとえば、上記の表現で 'Windows 98' に一致した場合、'98' の後からではなく 'Windows' の後から検索が再開されます。