Regex 懒惰量词在PCRE中究竟是如何工作的?
一点背景知识:我正在实现一个正则表达式匹配引擎(NFA),它应该支持PCRE兼容模式(我的意思是它应该捕获具有与PCRE相同偏移量的子表达式) PCRE的testinput1中有一个测试,我不能完全理解。它测试惰性量词 所以,正则表达式是Regex 懒惰量词在PCRE中究竟是如何工作的?,regex,nfa,Regex,Nfa,一点背景知识:我正在实现一个正则表达式匹配引擎(NFA),它应该支持PCRE兼容模式(我的意思是它应该捕获具有与PCRE相同偏移量的子表达式) PCRE的testinput1中有一个测试,我不能完全理解。它测试惰性量词 所以,正则表达式是 /<a[\s]+href[\s]*=[\s]* # find <a href= ([\"\'])? # find single or double quote (?(1) (.*?)
/<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
因此,关于PCRE回溯特定行为的建议很可能是错误的…首先,我只是REGEX领域的初学者。因此,如果这个答案是错误的,或者如果我误解了这个问题,我很抱歉 阅读本书中的定义: (?(1)then | else)是检查第一个捕获组 已经匹配了一些东西。如果有,正则表达式引擎将尝试匹配 那么。如果到目前为止捕获组还没有参加比赛, 尝试其他部分
- 关于这个主题:
我不完全理解您的问题,但是非贪婪量词允许搜索到模式的第一个出现。使用pcretest,您可以在相同的输入上尝试贪婪和非贪婪表单 非贪婪形式:
re> /<a[\s]+href[\s]*=[\s]*([\"\'])?(?(1)(.*?)\1|([^\s]+))/i data> <a href="ab"cd" 0: <a href="ab" 1: " 2: ab
re> /<a[\s]+href[\s]*=[\s]*([\"\'])?(?(1)(.*)\1|([^\s]+))/i data> <a href="ab"cd" 0: <a href="ab"cd" 1: " 2: ab"cd
re>/我曾经犯过一个错误,就是看了看它是如何完成的。吓人的!就我所见,完整的PCRE需要堆栈评估模型,而不是自动机理论模型。使用基于自动机的方法最接近的可能是PostgreSQL和Tcl中使用的重新引擎,但这真的很复杂。感谢您的快速响应。但这似乎不是一种回溯特定行为(见编辑),可以使用自动机实现(尽管我知道TRE未能通过AT&T测试数据存储库中的POSIX合规性测试,因此,这种行为可能是一种“错误”)。
<a href="abcd
#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)
re> /<a[\s]+href[\s]*=[\s]*([\"\'])?(?(1)(.*?)\1|([^\s]+))/i data> <a href="ab"cd" 0: <a href="ab" 1: " 2: ab
re> /<a[\s]+href[\s]*=[\s]*([\"\'])?(?(1)(.*)\1|([^\s]+))/i data> <a href="ab"cd" 0: <a href="ab"cd" 1: " 2: ab"cd