貪欲でない一致が機能しています-正規表現を満たす最短の文字列を取得します。覚えておかなければならないのは、正規表現は左から右へのプロセスであるということです。したがって、最初のQに一致し、次にXYZが続く最短の文字数を取得します。Qを超えないようにするには、否定された文字クラスを使用する必要があります。
Q[^Q]*?XYZ
[^ Q]は、Qではない任意の1文字に一致します。これは1文字に対してのみ機能することに注意してください。開始区切り文字が複数の文字である場合は、別の方法で行う必要があります。なんで?さて、区切り文字「PQR」を取ると、文字列は
foo PQR bar XYZ
以前の正規表現を使用しようとしたが、文字クラスを次のように拡張した場合:
PQR[^PQR]*?XYZ
その後、あなたは得るでしょう
'PQR bar XYZ'
さすがに。しかし、あなたの文字列が
foo PQR Party Time! XYZ
一致するものはありません。これは、[]が「文字クラス」を表すためです。これは正確に1つの文字に一致します。これらのクラスを使用すると、それらをリストするだけで、文字の範囲を一致させることができます。
th[ae]n
'than'と'then'の両方に一致しますが、'thin'には一致しません。最初にカラット('^')を配置すると、クラスが無効になります。つまり、「これらの文字以外のものに一致する」という意味です。したがって、「PQR」ではなく、1文字の区切り文字を[^ PQR]に変換することで、「 「「P」、「Q」、または「R」ではない」と言い換えます。必要に応じてこれを使用することもできますが、区切り文字の文字が区切り文字にのみ含まれることが100%確実である場合に限ります。その場合は、欲張りマッチングを使用して、区切り文字の最初の文字のみを無効にする方が高速です。その正規表現は次のようになります。
PQR[^P]*XYZ
ただし、その保証ができない場合は、次のように一致させてください。
PQR(?:.(?!PQR))*?XYZ
正規表現は、負の文字列照合を直接サポートしていません(それについて考えると、定義することが不可能であるため)。したがって、負の先読みを使用する必要があります。
(?!PQR)
まさにそのような先読みです。これは、「次の数文字はこの内部正規表現ではないことを表明する」という意味で、どの文字とも一致しません。
.(?!PQR)
PQRが後に続かない任意の文字に一致します。それをグループにまとめて、怠惰に繰り返すことができるようにします。
(.(?!PQR))*?
「区切り文字を含まない文字列」に一致します。私がした唯一のことは、それを非キャプチャグループにするために?:を追加することでした。
(?:.(?!PQR))*?
正規表現の解析に使用する言語によっては、一致したすべてのグループを個別に返そうとする場合があります(検索と置換に役立ちます)。これはそれがそれをするのを防ぎます。
よろしくお願いします!