Tcl贪婪的子表达式+和*之间的差异

1 regex tcl regex-greedy

我试图理解Tcl子表达式匹配和"贪婪",并且完全难以理解正在发生的事情.参考http://wiki.tcl.tk/396上的示例:

%regexp -inline (.*?)(n+)(.*) ennui
en e n {} 
%regexp -inline ^(.*?)(n+)(.*)$ ennui
ennui e nn ui
Run Code Online (Sandbox Code Playgroud)

尽管我没有完全理解"嵌套表达式"(这是括号表示的,对吗?)匹配,但我决定从小开始,尝试将*和+之间的区别作为贪婪的运算符:

% regexp -inline (.*)(u*)(.*) ennui
ennui ennui {} {}
% regexp -inline (.*)(u+)(.*) ennui
ennui enn u i
Run Code Online (Sandbox Code Playgroud)

如果*匹配零或更多,+匹配一个或多个,我不明白两个命令之间输出的差异.为什么u*和u +在同一个字符串上产生两个不同的结果?

我觉得这是一个非常重要的细微差别 - 如果我能掌握这个简单模式匹配/正则表达式中正在发生的事情,我的生活将会变得完整.救命!

提前致谢.

gle*_*man 5

关于非贪婪.Tcl正则表达式有一个怪癖:表达式中的第一个量词设置整个表达式的贪婪.(参见re_syntax手册页的"匹配"部分,密切注意" 偏好 " 一词):

分支与其中具有偏好的第一个量化原子具有相同的偏好.

%regexp -inline (.*?)(n+)(.*) ennui
en e n {} 
Run Code Online (Sandbox Code Playgroud)
  • (.*?) 抓取零个或多个字符,更喜欢最短的匹配
  • (n+)抓住一个或多个n,继承最短的偏好
  • (.*) 抓取零个或多个字符,继承最短的偏好

第一个子表达式匹配第一个字符,但不包括第一个字符n.第二部分匹配一部分n.第三部分匹配第一个和第二个之间的零个字符n.

我有点惊讶的是,第一个子表达式捕获了一个e而不是在第一个子表达式之前捕获零个字符n,但这可以通过匹配到正则表达式引擎的"最左边"优先级来解释:

如果RE可以匹配给定字符串的多个子字符串,则RE匹配字符串中最早开始的字符串.

无法表达的结果也让我感到惊讶:我本来期待的e n nui不是e nn ui.添加$锚似乎已经放弃了表达式对最短匹配的偏好.