一点背景知识:我正在实现一个正则表达式匹配引擎(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 行为的解释或任何细节/建议,为什么惰性量词在这个测试中匹配。谢谢!
编辑:我还检查了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 的回溯特定行为的建议很可能是错误的......