|
HmJre.dllにおける正規表現(Ver3.53対応版)
HmJre.dllでは、山田和夫氏作のJRE32.DLLをベースに少しだけ正規表現を拡張しています。
拡張したのは以下の形式です。
- パターンの繰り返し回数指定
-
{n}
{n,}
{n,m}
- 後方一致指定(V1.50にて一部拡張)
-
(?=expression)
- 後方不一致指定(V1.50にて一部拡張)
-
(?!expression)
- 前方一致指定
-
(?<=expression)
- 前方不一致指定
-
(?<!expression)
- 一般的正規表現互換のタグ付き正規表現(V1.50から)
-
\1 \2 ...
- 繰り返しマッチングでのものぐさ指定
-
*?
+?
??
{n,m}?
- ヒットした扱いにするタグ指定(HmJre.dll独自形式)
-
(?\tag-number)
- Perl互換の各種指定 (V3.00から)
-
\s (半角空白/タブ/改行にマッチ)
\S (半角空白/タブ/改行以外にマッチ)
\d (数字にマッチ、[0-9]と同じ)
\D (数字以外にマッチ、[^0-9]と同じ)
\c (英数字にマッチ、[a-zA-Z0-9_]と同じ)
\C (英数字以外にマッチ、[^a-zA-Z0-9_]と同じ)
\i (英字にマッチ、[a-zA-Z_]と同じ)
\I (英字以外にマッチ、[^a-zA-Z_]と同じ)
\y (単語の区切りにマッチ)
\Y (単語の区切りじゃない所にマッチ)
- タグ指定出来ない括弧 (V3.00から)
-
(?:expression)
- メタ文字を文字と見なす (V3.02から)
-
\Q...\E
- コメント (V3.00から)
-
(?#expression)
- セーフモード (V3.51から)
-
(?#safemode)
- 繰り返し指定その1(固定回数)
-
特定の正規表現パターンをn回繰り返す場合には、{n}を使います。nの部分には数値が入ります。例えばabcを3回繰り返すには、(abc){3}と記述します。
数字を5回繰り返すには、[0-9]{5}と書きます。
- 繰り返し指定その2(n回以上)
-
特定の正規表現パターンがn回以上出てくることにマッチさせるには、{n,}を使います。nの部分には数値が入ります。例えばabcが3回以上繰り返すには、(abc){3,}と記述します。
- 繰り返し指定その3(n回以上、m回以下)
-
特定の正規表現パターンがn回以上m回以下出てくることにマッチさせるには、{n,m}を使います。nおよびmの部分には数値が入ります。
- 後方一致指定
-
特定の正規表現パターンの後に、さらに特定の正規表現パターンが続くことを指定しつつ、正規表現にヒットする文字列としては前方部分のみとするような指定が出来ます。
例えば、「abcxyz」という文字列を検索しつつ、ヒットする文字としては「abc」だけにしたいようなケースに使います。普通の検索では必要ありませんが、強調表示や置換の時に使うと便利です。
例えば「abc」の後に「xyz」が続きつつ、ヒットする文字列は「abc」だけにしたい場合は、
abc(?=xyz)
と指定します。
後方一致指定の後ろにさらにパターンを指定すると、両方のAND指定という意味になります。例えば、
abc(?=[a-z])([x-z])
と指定すると、a-zでなおかつx-zにマッチする文字列にヒットします。このような表記とタグ付き正規表見を組み合わせるといろいろ応用範囲が広がります。
- 後方不一致指定
-
後方一致指定とは反対に、後方部分が特定のパターンにヒットしないことを必要とします。例えば「abc」の後ろが「xyz」でない場合に「abc」のみにヒットさせたいようなケースで使います。
上記例では、
abc(?!xyz)
と指定します。
後方不一致指定の後ろにさらにパターンを指定すると、両方のAND指定という意味になります。例えば、
([a-z])((?!\1)[a-z])\2
というパターンを使うことにより、「1文字目と2文字目は一致しなけども2文字目と3文字が一致する3文字の英単語」を検索することが出来ます。
- 前方一致指定
-
特定の正規表現パターンの前に、さらに特定の正規表現パターンが存在していることを指定しつつ、正規表現にヒットする文字列としては後方部分のみとするような指定が出来ます。
例えば、「abcxyz」という文字列を検索しつつ、ヒットする文字としては「xyz」だけにしたいようなケースに使います。普通の検索では必要ありませんが、強調表示や置換の時に使うと便利です。
例えば「abc」の後に「xyz」が続きつつ、ヒットする文字列は「xyz」だけにしたい場合は、
(?<=abc)xyz
と指定します。
前方一致指定は、正規表現文字列の先頭に書く必要があります。また、前方一致指定の表記自体をカッコで囲んだり「|」などと組み合わせることは出来ません。そういう指定をしてもエラーにはなりませんが、間違った検索を実行してしまいます。
検索系コマンドでの次候補/下候補系コマンド実行時の注意:
例えば上記のような検索例で、「abcxyz」の先頭からではなく、例えば「b」の部分から検索を開始した場合、残念ながらHmJre.dllではxyz部分にうまくヒットしません。xyz部分にヒットさせるには、abcxyzの先頭から検索する必要があります。
改行文字の指定についての制限:
前方一致/前方不一致指定の括弧の中には改行文字を入れることが出来ません。無理矢理改行文字を入れて検索してもうまくヒットしない可能性が高いです。
- 前方不一致指定
-
前方一致指定とは反対に、前方部分が特定のパターンにヒットしないことを必要とします。例えば「xyz」の前が「abc」でない場合に「xyz」のみにヒットさせたいようなケースで使います。
上記例では、
(?<!abc)xyz
と指定します。
前方不一致指定は、正規表現文字列の先頭に書く必要があります。また、前方一致指定の表記自体をカッコで囲んだり「|」などと組み合わせることは出来ません。そういう指定をしてもエラーにはなりませんが、間違った検索を実行してしまいます。
検索系コマンドでの次候補/下候補系コマンド実行時の注意:
前方一致指定と同じく、前方不一致の正規表現のマッチングも、検索開始位置として指定された位置から実行されます。それより前の部分については一致/不一致のチェックは行われません。
例えば上の例で、「abcxyz」の「x」の部分から検索を開始してしまうとヒットしてしまいます。
改行文字の指定についての制限:
前方一致/前方不一致指定の括弧の中には改行文字を入れることが出来ません。無理矢理改行文字を入れて検索してもうまくヒットしない可能性が高いです。
- ものぐさ(non-greedy)指定
-
「*」、「+」、「?」、「{n,m}」のような繰り返し指定は、原則として、もっとも長い文字列にマッチさせるように動作します。例えば「a*」の指定が"a"の文字が連続している文字列にヒットするとき、"a"の全体にヒットします。
ものぐさ指定をした場合は、逆に、もっとも短い文字列にヒットしようとします。例えば「a*?」だけ指定すると、それは0文字にヒットします。
例えば、「<」で始まって「>」で終わる文字列にヒットさせるために、「<.*>」と正規表現指定すると、それはそれで正しくヒットしますが、それだと「<AAA>CCC<BBB>」のような文字列の全体にヒットしてしまって都合が悪いです。そういう時に、ものぐさ指定して、例えば「<.*?>」のように指定すると、<AAA>の部分と<BBB>の部分の2つに分けてヒットして、とても便利です。
また、正規表現のマッチング処理自体も、ものぐさ指定した方が動作速度が速くなる可能性が高いです。
- 一般的正規表現互換のタグ付き正規表現
-
秀丸に従来から備わっているタグ付き正規表現は、"\f"という記号で検索パターンを区切ります。Perl等でのタグ付き正規表現では、カッコを使ってターゲットを指定する形になっています。そのPerl等と同じ方式のタグ指定が、HmJre.dllでも出来ます。こっちの方式でタグ指定する場合は、その指定されたタグを検索パターンの中に入れることも出来ます。
こちらのやり方としては、タグ指定したい部分をカッコで囲みます。例えば、英数字と数字の組み合わせを検索しつつ、そのヒットした部分の数字の部分だけをタグ指定したい場合は、その数字に相当する部分をカッコで囲みます。
[a-z]+([0-9]+)
のように指定します。そして、タグとしては、\1というのが数字の部分に相当することになります。または、
([a-z]+)([0-9]+)
のようなパターンを指定した場合は、英字の部分が\1になり、数字の部分が\2となります。
タグの対象となるのはあくまで一番ネストの浅いカッコだけなので、例えば、
(aaa|(bbb|ccc))
と指定した場合には、それ全体が\1に相当し、\2、\3に該当する物は存在しないことになります。
「\1」等を検索文字列の中に入れることも出来ます。例えば、
\<([a-z])((?!\1)[a-z])\2\>
と指定すると、"see"や"all"のような、1文字目と2文字目は一致しないけども2文字目と3文字目が一致する3文字の単語を検索することが出来ます。
補足:
前方一致/不一致、後方一致/不一致指定についてはタグ付き正規表現でのカッコの対象外となります。例えば、"(aaa)(?!bbb)(ccc)"というパターンを指定した場合での"\2"に該当する部分は(ccc)部分となります。
- ヒットした扱いにするタグ指定(HmJre.dll独自形式)
-
(?\tag-number)の形式を使うことで、検索でヒットした扱いにする部分を、検索パターン中のタグの指定で行うことが出来ます。前方一致/前方不一致指定などを使ってもいいんですけど、それとは別にこういうのも対応しました。
例えば、aaabbbcccという文字列を検索しつつも、ヒットした扱いにしたいのがbbbだとすると、
(?\2)(aaa)(bbb)(ccc)
と指定すればいいです。(?\tag-number)の指定は正規表現パターンのどこに入れてもかまいません。複数指定した場合は一番最後に指定した方のみが有効となります。
制限事項
複数行にマッチするような正規表現パターンについて、(?\tag-number)の指定で2行目以降にマッチする文字列を限定するような指定をすると、秀丸エディタの検索上は、その文字列にはマッチしない扱いになってしまいます。これは秀丸エディタの検索処理の制限上、仕方がないということになってます。
- ユニコード文字による指定(HmJre.dll独自形式、V1.95から)
-
[...]または[^...]の中に限り、「\uXXXX」のような形で16進数のコードを使ってユニコードの文字を指定することが出来ます。
[...]または[^...]の中での文字コード範囲指定の時に「\uXXXX」のような指定を使うと、文字コードの範囲をユニコードで指定したという意味になります。例えば「[\u4E00-\uFA2D]」と指定すると、ユニコード文字での4E00〜FA2Dにヒットする意味になり、結果として日本語/中国語のすべての漢字にヒットするような表現が可能になります。
「\uXXXX」は、[...]および[^...]の外では使えません。
- サロゲートペアとなるユニコード文字の指定(HmJre.dll独自形式、V3.38から)
-
[...]または[^...]の中に限り、「\uXXXX」のような形で16進数のコードを使ってユニコードの文字を指定することが出来ますが、\uXXXXで表現出来るのは4桁に限ります。なので、16進数で4桁を超えるユニコード文字(いわゆるサロゲートペアの文字)は、この方法では指定することが出来ません。
HmJre.dllのV3.38から、
\u{XXXXX}
のような形で任意桁数のユニコード文字を指定出来るようになりました。例えばユニコード16進数で25055の文字は、「\u{25055}」のように書くことが出来ます。
\u{XXXXX}のような表記方法とは別に、サロゲートペアでの文字コードをそのまま「\uXXXX\uXXXX」と書いても同じ意味と解釈出来るようにもなりました。例えば\u{25055}の文字はサロゲートペアで表現すると「\uD854\uDC55」となります。
- Perl互換の各種指定 (V3.00から)
-
\s は、半角空白およびタブおよび改行文字(\n)にヒットします。[ \t\r\n]と書くのと同じです。
\S は、逆に、半角空白/タブ/改行以外にヒットします。[^ \t\r\n]と書くのと同じです。
\d は、数字にヒットします。[0-9]と同じです。
\D は、数字以外にヒットします。[^0-9]と同じです。
\c は、英数字と「_」にヒットします。[a-zA-Z0-9_]と同じです。Perlでは「\w」と書きますが、HmJre.dllでは、JRE32.DLLですでに\wが別の意味で使われている関係で、\cとなっています。その辺ご注意お願いします。
\C は、英数字と「_」以外にヒットします。[^a-zA-Z0-9_]と同じです。Perlでの「\W」と同じですが、HmJre.dllでは「\C」となっているので注意が必要です。
\i は、英字と「_」にヒットします。[a-zA-Z_]と同じです。
\I は、英字と「_」以外にヒットします。[^a-zA-Z_]と同じです。
\y は、英単語の区切りにヒットしますが、数字も単語の一部と見なす点で、「\<」や「\>」と少し意味が違ってきます。例えば「abc123」のような文字列があったとすると、その「abc」と「123」の間にはヒットしません。「abc xyz」という文字列があるとすると、「abc」とその次の空白の間および空白と「xyz」の間にはヒットします。「_」も英単語の一部と見なされます。Perlでは「\b」と書くことが多いようですが、HmJre.dllでは「\b」はバックスペース制御文字という扱いになっているので、「\y」となっています。
\Yは、「\y」の反対で、英単語の区切りじゃない所にヒットします。
これらの指定については、[...]および[^...]のキャラクタクラスの指定の中でも使えます。例えば[\d0-9]のように指定すると、半角数字と全角数字にヒットする条件が指定出来ます。(V3.04から指定出来るようになりました)
- タグ指定出来ない括弧 (V3.00から)
-
括弧が二重以上になる場合、\1、\2等のタグ指定の対象となるのは、普通、一番外側の括弧だけとななります。
(?:.....)のような形で一番外側の括弧を囲むと、タグ指定の対象となるのが、その1つ内側の括弧となります。
例えば
(?:(111)(222)(333))
のような正規表現パターンを指定すると、\1で参照出来るのが(111)、\2が(222)、\3が(333)の部分となります。
(?:(?:(111)(222)(333))|(444))
のような指定をすると、もしもそのパターンが「444」にヒットした場合には、\1、\2、\3は存在しない扱いとなり、「111222333」にヒットした場合は、\4が存在しない扱いとなります。
- メタ文字を文字と見なす (V3.02から)
-
\Qで始まって\Eで終わるような形で文字列を書くと、その中の文字列の中では、いわゆるメタ文字が普通の文字扱いになります。
例えば、"a.b"と書いた場合は、その中にある「.」はメタ文字での「任意の1文字」という意味になりますが「\Qa.b\E」と書くと、「a.b」という文字列そのものを表すことになります。
文字列の最後まですべてを対象としたい場合は\Eは省略してもかまいません。例えば「\Qa.b」は「\Qa.b\E」と同じです。
\Q\n\Eは、改行にはヒットしないで「\n」という文字列にヒットします。
- コメント (V3.00から)
-
(?#expression)のように書くと、その部分はコメント扱いとなり、正規表現のマッチング上は無視されます。
他の正規表現ライブラリ等ではコメント内ではカッコのネストが使えないようですが、HmJre.dllではV3.17付近からカッコのネストが使えるようになっています。例えば(?#xxx(yyy)zzz)と書くと、それ全体がコメント扱いとなります。
- セーフモード (V3.52から)
-
(?#safemode)と書くと、HmJre.dllが独自にやってる高速化の処理をしないようにして、なるべく正確に動作するように努力します。実はHmJre.dllが独自にやってる高速化のせいで、期待した長さにヒットせずに、より短い文字列にヒットしてしまうことがあります。(?#safemode)を指定すると、一応そういう誤動作が無くなり、可能な限り最大の長さの文字列にヒットするようになります。
例えば、「a+([ab]b)+」という正規表現パターンは、「aaabbb」の6文字にヒットしないといけないはずが、HmJre.dllでは5文字にヒットしてしまいます。(?#safemode)を付けると、正しく6文字にヒットします。
(?#safemode)を付ける位置は、正規表現パターンの先頭でも最後でも、どこでもかまいません。
(?#safemode)を付けないとうまくヒットしない他の例:
「a*(ab|aabb)」が「aabb」の4文字にヒットせず3文字にヒットしてしまう。
「(a.?)+」が「aax」の3文字にヒットせず2文字にヒットしてしまう。
「^(a.?)+$」が「axaax」にヒットしない。
「(|a){2}x」が「ax」」にヒットしない。(aを飛ばしてxにヒットする)
「(a|(?=x)){10}x」が「ax」にヒットしない。(aを飛ばしてxにヒットする)
「(a|aa)+?a」が「aaa」のうちの2文字にヒットせずに3文字にヒットしてしまう。
- その他
-
他の正規表現パターンについては、秀丸エディタのヘルプなりJRE32.DLLの説明なりを参照ください。
JRE32.DLLとの互換性を多少なりとも確保するために、{n}などの形式で間違いがあってもエラーにはなりません。例えば「a{」が指定された場合は、それは{n}などの指定ではなく、単に「a{」という文字列を検索する指定であると解釈されます。
|