正規表現

AutoHotkey v1.0.45以降では、RegExMatch()RegExReplace()で、正規表現による検索・置換が行える。
また、SetTitleMatchModeでRegExを指定すると、ウィンドウのタイトルなどの指定に正規表現を使用することが出来る。

AutoHotkeyで用意されている正規表現は、Perl 5に搭載されているものと概ね互換のPCRE(Perl Compatible Regular Expressions)である。
以下で説明するような表現を使用することで、様々なテキストを一つのパターン文字列で検索できる。

特殊な文字表現

特殊な文字は、直接正規表現中に埋め込んでも認識されるが、以下の表現でも表すことが出来る。

\C 任意の1バイト
\aアラーム、ベル文字(\x07)
\eエスケープ文字(\x1b)
\f改ページ(\x0c)
\n改行(\x0a)
\rキャリッジリターン(\x0d)
\tTab(\x09)
\cX各種制御文字。
Xで指定した文字のASCIIコードの上位2ビットを0にした文字。(Control-X)
例えば、「\cJ」は「\n」を表す。
\xHH HHで指定された16進数で表される1バイト。
例えば、「\x0a」は改行文字(\n)を表す。

また、.*?+[{|()^$\などの記号は、「\.」や「\[」のように、前に「\」を付けてエスケープする必要がある。
それ以外の文字は、「\」を付けても付けなくても同じになる。
例えば、「\@」は「@」を表す。
ただし、「X」オプションが有効になっている場合は、「\v」など、意味の用意されていないアルファベットをエスケープするとエラーになる。

複数の文字のどれかを意味する表現

以下のような表現を利用することで、条件に一致する文字1文字を表すことが出来る。

.改行を除く任意の文字
「s」オプションが指定されている場合は、改行も含む。
\w 1文字の単語構成文字([0-9a-zA-Z_])
\W 単語構成文字以外の1文字
\d 1文字の半角数字([0-9])
\D 半角数字以外の1文字
\s 1つの半角スペース
\S 半角スペース以外の1文字
[char-list] char-list内に列挙されたいずれかの文字
[^char-list] char-list内に列挙された文字以外の任意の文字

char-listには、単に文字を列挙するだけでなく、以下のような表現も使用可能である。
これらは、複数組み合わせて並べることも出来る。

c1-c2
c1からc2の間の文字(例:「0-9」)
\s,\S,\w,\W,\d,\D,\xHH
[:alnum:]
アルファベットと数字
[:alpha:]
アルファベット
[:word:]
単語構成文字
[:blank:]
空白文字(スペース、タブ等)
[:cntrl:]
制御文字
[:digit:]
十進数字
[:graph:]
印字可能かつ表示可能な文字(スペースは印字可能だが表示可能ではない)
[:lower:]
アルファベットの小文字
[:print:]
印字可能なキャラクタ(=制御文字以外のキャラクタ)
[:punct:]
句読点(通常の文字、数字、制御文字、スペースのいずれでもないキャラクター)
[:space:]
スペース、タブ、改ページ
[:upper:]
アルファベットの大文字
[:xdigit:]
十六進数字

繰り返しを表す正規表現

文字、文字クラス、式集合の後ろに以下の量指定子を付けると、パターンの繰り返しを表すことが出来る。
例えば、「\d+」は1文字以上の半角数字に、「(ab){1,3}」は「ab」または「abab」または「ababab」にマッチする。

?1回または0回
*0回以上
+1回以上
{n,m}n回以上m回以下
nとmの上限は65536
{n,}n回以上
{,n}0回以上n回以下 ({0,n})
{n}n回

なお、通常の量指定子は「貪欲」であり、複数のマッチ結果が考えられる場合、一番長くマッチするものが採用される。
「??」や「+?」、「{1,5}?」のように量指定子のあとに「?」を付けると、「無欲」になり、一番短くマッチするものを採用する。
例えば、「aaa<b>bbb</b>ccc」をターゲットに「<.*>」を検索した場合、「<b>bbb</b>」にマッチしてしまう。
「<.*?>」を検索すれば、「<b>」にマッチする。

「?+」や「*+」、「{1,5}+」のように、量指定子のあとに「+」を付けると、「強欲」になり、後ろに続くパターンにかかわらず必ず一番長くマッチしたものを採用するようになる。
例えば、「---abcdef---」をターゲットに「\w+f」を検索するとマッチするが、「\w++f」を検索するとマッチしない。「\w++」が何が何でも「abcdef」までを採用しようとして、後に続く正規表現に「f」を譲ろうとしないためである。

特定の場所にマッチする表現

以下の表現は、文字ではなく場所にマッチする。
例えば、「^」は「文字列の先頭の文字」ではなく、「先頭の文字の前」にマッチする。

^ 文字列の先頭。
「m」オプションが指定されている場合は、各行の行頭。
$ 文字列の末尾。
ただし、末尾が改行だった場合、その直前にマッチ。(「D」オプションが指定されている場合は、本当の末尾にマッチ)
「m」オプションが指定されている場合は、各行の行末。
\A 「m」オプションの有無にかかわらず、文字列の先頭
\Z 「m」オプションの有無にかかわらず、文字列の末尾。
ただし、末尾が改行だった場合、その直前にマッチ。(「D」オプションが指定されている場合は、本当の末尾にマッチ)
\z 「m」オプションや「D」オプションの有無にかかわらず、文字列の本当の末尾
\G 検索の開始位置。
RegExMatch()のStartingPosで指定した位置。
RegExReplace()における2つめ以降の置換では、前回マッチした範囲の直後になる。
\b 単語の区切り。
\w(単語構成文字)に該当する文字と\W(非単語構成文字)に該当する文字が隣り合っているような場所
\B 単語の途中。
\w(単語構成文字)に該当する文字が隣り合っているような場所

選択

|」で区切ることで、複数の正規表現の内どれか一つにマッチする文字列を検索できる。
Shift|Ctrl|Alt」のように、3つ以上を並べてもよい。
正規表現の途中に組み込みたい場合は、後述のグループ化を使用し、「(Shift|Ctrl|Alt)+[A-Z]」のようにする。

regexp1|regexp2 regexp1とregexp2のどちらかにマッチ

なお、「|」で区切って並べられた正規表現は、一番左のものからテストされ、最初にマッチしたものより右のものはテストされない。
例えば、「Auto(\w+)」と「(\w+)Hotkey」はいずれも「AutoHotkey」にマッチするが、「Auto(\w+)|(\w+)Hotkey」を「AutoHotkey」にマッチさせた場合、「(\w+)Hotkey」の部分は使用されず、「\2」は空になる。

グループ化

正規表現を「(」「)」で囲むことでグループ化できる。
正規表現の途中に「|」による選択などを含めたい場合や、マッチした文字列を後述の後方参照で使用したい場合などに使用する。

(regexp)グループ化し、番号に関連づける
番号は、「(」の出現した順番に1から割り振られる。
(?P<name>regexp) グループ化し、nameで指定した名前に関連づける。
同時に、番号にも関連付けが行われる。
(?:regexp)グループ化のみ行い、番号に関連付けしない
(?>regexp)regexpを検索するが、マッチしたあとバックトラックしない(強欲)
番号には関連付けされない
(?:regexp){1}+」とほぼ同じ。

グループにマッチした文字列の呼び出し(後方参照)

以下の表現を使用することで、グループ化された正規表現にマッチした文字列と同じ文字列を検索できる。
例えば、「<(\w+).*?>.*?</\1>」は、任意のHTMLタグから対応する終了タグまでの文字列にマッチする。

\num numで指定した番号に関連づけられたグループに最後にマッチした文字列と同じものにマッチ(\1〜\99)
(?P=name) nameで指定した名前に関連づけられたグループに最後にマッチした文字列と同じものにマッチ

先読み・戻り読み

先読みでは、直後に特定のパターンに一致する文字列が存在するような場所にマッチする。
一旦先の文字列を調べたあと、元の場所に戻ってくるので「先読み」という。
この機能を利用することで、複雑な条件で検索したり、置換の正規表現を簡略化したり出来る。

(?=regexp) regexpにマッチする文字列の直前にマッチ
(?!regexp) regexpにマッチする文字列の直前でない場所にマッチ
(?<=regexp) regexpにマッチする文字列の直後にマッチ
regexpは長さがあらかじめ確定しているような正規表現でなくてはならない
(?<!regexp) regexpにマッチする文字列の直後でない場所にマッチ
regexpは長さがあらかじめ確定しているような正規表現でなくてはならない

再帰呼び出し

以下の表現を使用することで、正規表現の全部または一部を呼び出して使用できる。
この呼び出しは、呼び出す正規表現自体の中に記述することも出来る。
例えば、「カッコで囲まれた文字列」という正規表現の中に、その正規表現の再帰呼び出しを組み込むことで、カッコが入れ子になった文字列を正しく検索できる。

(?R) 正規表現全体を再帰呼び出し
(?num) 番号指定でグループを(再帰)呼び出し(「(?1)」〜「(?99)」)
(?P>name) 名前付きグループを(再帰)呼び出し

条件分岐

条件に一致するときだけ特定のパターンを検索したり、条件に応じて検索するパターンを切り替えたりすることが出来る。

(?(condition)yes-regexp|no-regexp) conditionが真の時はyes-regexp、偽の時はno-regexpを使用してマッチングを行う
(?(condition)yes-regexp) conditionが真の時はyes-regexpを使用してマッチングを行うが、偽の時は何も行わない。
「(?(condition)yes-regexp|)」と同じ。

conditionに数字や名前を指定した場合は、その正規表現グループにマッチするものがあったときに真になる。
先読みや戻り読みの条件を記述することも出来る。

また、「R」を指定した場合は、再帰呼び出しで呼び出されている際に真になる。
これにより、1段階だけ入れ子になっているような文字列を検索できる。

オプションの部分的変更

後述のオプションは、正規表現の途中で一部だけ別の設定に変更することも出来る。

(?imsxUX-imsxUX)以降のオプションを変更
(?imsxUX-imsxUX:regexp) regexpの部分のオプションを変更

imsxUX-imsxUXにはONにするオプションとOFFにするオプションを記述する。
例えば、「i」にすると「i」オプションがONに、「-i」にすると「i」オプションがOFFになる。
「i-s」とすると「i」オプションがONになりつつ「s」オプションがOFFになる。

コメント

(?#text)正規表現中にコメントを埋め込むことが出来る。
コメントになっている部分は、実際には無視される。
なお、textに「)」を含むことは出来ないので注意。

オプション

AutoHotkeの正規表現では、パターンの最初に「)」で区切ってオプションを指定する。
用意されているオプションは以下の通り。

i
半角アルファベットの大文字・小文字を区別しない
m
「^」と「$」が各行の行頭・行末にマッチするようになる。
s
.」で改行文字もマッチするようにする
x
パターン中の空白文字(半角スペース、Tab文字、改行文字)と、「#」から行末までの文字列を無視する。
「[]」内の文字は、無視されない。
長い正規表現をテキストファイルなどに記述して、コメントなどを含めたい場合に使用する
A
マッチ箇所の始まりが検索開始位置と一致していなければならないようにする
D
文字列の末尾が改行だったときでも、「$」が文字列の本当の末尾にマッチするようにする。
「m」オプションが指定されているときは無視される。
J
同名の名前付き捕獲式集合を許可する
U
「*」「+」「?」「{n,m}」などの量指定子のデフォルトを無欲(出来るだけ短いものにマッチ)にする。 逆に、「*?」「+?」「??」「{n,m}?」などは、貪欲(出来るだけ長い物にマッチ)になる。
X
PerlにはないPCRE独自の機能を有効にする。
通常は、「\g」のように特別の意味の用意されていないアルファベットを「\」でエスケープしたとき、「g」を表しているものとみなすが、「X」オプションが指定されていると、正規表現構文エラーとして扱われる。
将来のPCREの拡張で「\g」に特別な意味が与えられたときに異常が発生することを予防できる。
S
時間をかけて詳細にパターンを分析する代わりに、マッチング処理を高速化する。
複雑な正規表現を何度も使用する場合に有効。
一度分析された正規表現は、最大で100個までキャッシュされて、同じ正規表現を使用する際に分析処理を省略できる。
`n
.」記号や、「m」オプション、「D」オプションなどで「改行」として扱われる文字を「`n」にする。
デフォルトは「`r`n」。
`r
改行を「`r」にする。

2バイト文字への対応

仮名や漢字などの2バイト文字は考慮されない。