クイックスタート
チュートリアル
ツールと言語
リファレンス
書籍レビュー
正規表現チュートリアル
はじめに
目次
特殊文字
印字不能文字
正規表現エンジンの内部
文字クラス
文字クラスの減算
文字クラスの積集合
短縮文字クラス
ドット
アンカー
単語境界
選択
オプション項目
繰り返し
グループ化とキャプチャ
後方参照
後方参照 パート2
名前付きグループ
相対後方参照
分岐リセットグループ
フリースペーシングとコメント
Unicode
モード修飾子
アトミックグループ
所有量指定子
先読みと後読み
先読みと後読み パート2
一致からテキストを除外する
条件分岐
バランスグループ
再帰
サブルーチン
無限再帰
再帰と量指定子
再帰とキャプチャ
再帰と後方参照
再帰とバックトラッキング
POSIX ブラケット式
長さゼロの一致
継続一致
このサイトの詳細
はじめに
正規表現クイックスタート
正規表現チュートリアル
置換文字列チュートリアル
アプリケーションと言語
正規表現の例
正規表現リファレンス
置換文字列リファレンス
書籍レビュー
印刷可能なPDF
このサイトについて
RSSフィードとブログ
RegexBuddy—Better than a regular expression tutorial!

これまでに一致したテキストを全体の正規表現一致から除外する

後読みは、他のテキストが前にある特定のテキストに一致させるためによく使用されますが、他のテキストは全体の正規表現一致には含まれません。(?<=h)dは2番目のdのみに一致しますadhd。多くの正規表現フレーバーは後読みをサポートしていますが、ほとんどの正規表現フレーバーは後読み内で使用できる正規表現構文のサブセットのみを許可します。 PerlBoostは、後読みが固定長である必要があります。 PCRERubyは、異なる長さの選択肢を許可しますが、それでも固定長の量指定子{n}.

以外は許可しません。後読みの制限を克服するために、Perl 5.10、PCRE 7.2、Ruby 2.0、およびBoost 1.42は、最も一般的な目的に後読みの代わりに使用できる新しい機能を導入しました。\Kは、これまでに一致したテキストを全体の正規表現一致から除外します。h\Kdは2番目のdのみに一致しますadhd.

JGsoftフレーバーは、\Kよりもはるかに柔軟な、無制限の後読みを常にサポートしてきました。それでも、JGsoft V2は\Kのサポートを追加しているので、この方法で作業したい場合は使用できます。

正規表現エンジンの内部を見る

h\Kdの動作を見てみましょう。エンジンは文字列の先頭から一致の試行を開始します。haと一致しません。試行する選択肢はもうありません。文字列の先頭からの試行は失敗しました。

エンジンは文字列内を1文字進めて、再度一致を試みます。hd.

再び進めると、hhと一致します。エンジンは正規表現を進めます。正規表現は\Kに達し、文字列内のhと2番目のdの間の位置にあります。\Khdの間に、実際には最初のdhの間に開始されたのではなく、この一致の試行が成功した場合に、正規表現エンジンは一致の試行が現在の位置で開始されたかのように見せかける必要があることを伝える以外は何もしません。

エンジンは正規表現を進めます。dは文字列の2番目のdと一致します。全体的な一致が見つかりました。\Kによって保存された位置のため、文字列の2番目のdが全体的な一致として返されます。

\Khhh\Kddのみに一致しますhhhhdと一致します。この正規表現は、最初に文字列の先頭にあるhhhと一致します。次に\Kは文字列内のhhhhdの間の位置を記録します。次にdは文字列の4番目のhと一致しません。文字列の先頭からの試行は失敗しました。

エンジンは、次の試行を開始する前に、文字列内を1文字進める必要があります。一致の試行の実際の開始位置、つまり文字列の先頭から進めます。\Kによって格納された位置は、これを変更しません。そのため、2番目の一致の試行は、文字列の最初のhの後の位置から始まります。そこから開始すると、hhhhhh, \Kは位置を記録し、ddと一致します。ここで、\Kによって記憶された位置が考慮され、dが全体的な一致として返されます。.

\Kはどこでも使用できる

\Kは、どの正規表現でもほぼどこでも使用できます。後読み内での使用のみ避ける必要があります。グループ内でも、量指定子がある場合でも使用できます。正規表現には、\Kのインスタンスを好きなだけ含めることができます。(ab\Kc|d\Ke)fcfabが前にある場合に一致します。また、cfd.

\Kef(ab\Kc|d\Ke)fにも一致します。\Kはキャプチャグループに影響を与えません。正規表現が\Kabcが前にある場合に一致します。また、と一致する場合、キャプチャグループはde.

\Kの制限

\K\K\K\K

の左側に何でも配置できますが、後読みの内部に配置できるものに制限されます。

しかし、この柔軟性には代償が伴います。後読みは実際に文字列内を逆方向に移動します。これにより、後読みは一致の試行の開始前に一致をチェックできます。一致の試行が前の 一致の終わりに開始された場合、後読みは前の 一致の一部であったテキストに一致させることができます。\K\K

は、正規表現エンジンが 一致プロセスを実行する方法に影響を与えないため、これを行うことができません。

文字列(?<=a)a内のaaaaのすべての一致を反復処理すると、3つの一致が得られます。文字列の2番目、3番目、および4番目のaaaa

の間で開始され、後読みが成功し、2番目のaaaa

の後に開始されます。ここでは後読みも成功します。前のaa

が前の一致の一部であったかどうかは関係ありません。したがって、3番目の一致の試行は3番目のaaaa

と一致します。5番目の一致の試行は文字列の終わりから始まります。後読みは引き続き成功しますが、aa

と一致する文字が残っていません。 一致の試行は失敗します。エンジンは文字列の終わりに達し、反復処理は停止します。5つの一致の試行で3つの一致が見つかりました。 a\Ka内のaaaaを反復処理すると、状況は異なります。2つの一致のみが得られます。2番目と4番目のaaaa

は最初のaの間の位置にあります。\Ka

と一致します。aは文字列の2番目のaaaa

の後に開始されます。正規表現の最初のaa

は3番目のaの間の位置にあります。\Ka

と一致します。aa

と一致します。2番目のaaaa

と一致しません。 一致の試行は失敗します。エンジンは文字列の終わりに達し、反復処理は停止します。3つの一致の試行で2つの一致が見つかりました。

基本的に、\K\K\K\K

の後の正規表現の部分と同じテキストに一致できる場合に、この問題が発生します。これらの部分が同じテキストに一致できない場合、\K\K\K\K

を使用する必要があります。これにより、Perl、PCRE、およびRubyのパフォーマンスが向上します。

もう1つの制限は、後読みには肯定形と否定形のバリアントがありますが、\K\K

は何も否定する方法を提供していません。 (?<!a)bは文字列b全体に一致します。「a」が前にない「b」だからです。[^a]\Kbは文字列bb[^a]b\Kbbb

と一致するものが残っていません。 一致の試行は失敗します。 [^a]\Kb[^a]\Kb(?<=[^a])bと同じで、どちらも(?<!a)b.