Немного предыстории: я реализую механизм сопоставления регулярных выражений (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 поведении с возвратом, скорее всего, неверно ...