ちょっとした背景: 私は正規表現マッチング エンジン (NFA) を実装しており、PCRE 互換モードをサポートする必要があります (つまり、PCRE と同じオフセットで部分式をキャプチャする必要があります)。
PCRE の testinput1 には、完全には理解できないテストがあります。遅延量指定子をテストします。
したがって、正規表現は
/<a[\s]+href[\s]*=[\s]* # find <a href=
([\"\'])? # find single or double quote
(?(1) (.*?)\1 | ([^\s]+)) # if quote found, match up to next matching
# quote, otherwise match up to next space
/isx
そして文字列は
<a href="abcd xyz pqr" cats
PCRE の試合は次のとおりです。
<a href="abcd xyz pqr"
明らかに遅延量指定子を使用しています。
私が理解している限り、別の「貪欲な」方法がまったく不可能になるまで、遅延量指定子を使用しないでください。ここで可能な貪欲な一致は次のとおりです。
<a href="abcd
条件付きサブパターンの負の分岐を使用し、遅延量指定子は使用しません。
したがって、この PCRE の動作の説明、または遅延量指定子がこのテストで一致する理由の詳細/提案を探しています。ありがとう!
EDIT : TREライブラリの仕組みも調べました。POSIX 互換の NFA エンジンです。TRE の構文に合わせて元の正規表現を少し変更しました。
#include <stdlib.h>
#include <stdio.h>
#include <tre/tre.h>
int main()
{
regex_t preg;
const char * regex = "<a[ ]+href[ ]*=[ ]*(?:(')(.*?)'|[^ ]+)";
const char * string = "<a href='abcd xyz pqr' cats";
int cflags = REG_EXTENDED;
int eflags = 0;
size_t nmatch = 3;
regmatch_t pmatch[100];
tre_regcomp(&preg, regex, cflags);
tre_regexec(&preg, string, nmatch, pmatch, eflags);
for (int i = 0; i < nmatch; i++) {
printf("%d: (%d, %d)\n", i, pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so);
}
return 0;
}
出力 (終了オフセットの代わりに長さを使用) は次のとおりです。
0: (0, 22)
1: (8, 1)
2: (9, 12)
したがって、PCRE のバックトラッキング固有の動作に関する提案は、おそらく間違っています...