TCL中匹配正则表达式出现问题

3
我正在使用以下模式:
Notif[0]:
some text multiple line
Notif[1]:
multiple line text
Notif[2]:
text again
Notif[3]:
text again
Finish

我正在编写以下正则表达式。
set notifList [regexp -inline -all -nocase {Notif\[\d+\].*?(?=Notif|Finish)} $var]

它没有给出期望的输出

需要的输出

I need a list with each `Notif`block
1个回答

2
原因是你的.*?作为贪婪子模式(=.*匹配0+任何字符,包括换行符),因为模式中的第一个量词是贪婪的(参见\d+)。请参阅Tcl Regex参考

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

你只需要在第一个+量化的子模式后面添加一个?,将其变成懒惰模式即可。
Notif\[\d+?\].*?(?=Notif|Finish)
          ^

这将防止.*?模式从\d+继承贪婪性。
请参见IDEONE演示

是的,你也可以使用 unrolled 的 贪婪 正则表达式模式,例如 Notif[\d+][^NF]*(?:(?:N(?!otif)|F(?!inish))[^NF]*)*,但它不太易读。但是,它更有效率。 - Wiktor Stribiżew
需要更多的解释。? 如何帮助? - Sumit
一个分支中的所有量词都会切换到相同的贪婪度,第一个遇到的设置贪婪度类型:懒惰或贪婪。+匹配尽可能多的1个或多个字符。因此,您模式中的最后一个.*?匹配到最后一个FinishNotif之前的所有文本。在+后添加?使.*?保持其懒惰含义,匹配到第一个NotifFinish - Wiktor Stribiżew
严格来说,它们都是同一个有限自动机中的量词。从某种程度上来说很容易理解,但在与正则表达式的关联上几乎是不可能的,除非在某些特定点上(所以(?=…)是其中一个简单的情况)。 - Donal Fellows

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接