我的模式如下:substring1(substring2),(xxxx)xxxx
需要substring1
(第一个括号前的字符串)和substring2
(第一个括号内的字符串),这是没有问题的。
此外,需要在一个子字符串中的第一个括号后面的所有字符 - 这些字符可能是括号本身。
因此使用模式 - regexp {(.*?)\((.*?)\)(.*)} $a match sub1 sub2 sub3
但是最后一个子字符串无法在sub3
中收集。
请帮帮我!
> 247 % set a substring1(substring2),(xxxx)xxxx
> 248 % regexp {(.*?)\((.*?)\)(.*)} $a match sub1 sub2 sub3 1
> 249 % puts $sub1; puts $sub2; puts $sub3
substring1
substring2
> 250 %
答案 0 :(得分:4)
你遇到的问题是Tcl的RE引擎是自动理论的,并且不能很好地应对切换贪婪模式。特别地,对于第一近似,情况是字符串中的第一个量词设置整个RE的贪婪。 (事实并非如此,但是当它切换时的规则是非常神秘的。)
如果您没有嵌套括号,可以使用:
regexp {^([^()]*)\(([^()]*)\)(.*)$} $a match sub1 sub2 sub3
测试(省略明显的位):
% puts $sub1|$sub2|$sub3
substring1|substring2|,(xxxx)xxxx
处理嵌套括号要困难得多。问题在于任意嵌套是你停止处理“语言”的地方,这种“语言”可以通过有限自动机正式匹配(相反,你需要一个下推自动机,这是一个不同的可判定性类)。对于有限级别的嵌套,您可以对其进行编码;这是如何用一个级别来做的:
regexp {^([^(]*)\(((?:[^()]|\([^()]*\))*)\)(.*)$} $a match sub1 sub2 sub3
也就是说,我将[^()]
替换为(?:[^()]|\([^()]*\))
。您可以根据需要随时更换第二个子[^()]
。然而,这使得RE更复杂(实际上这是问题;任意嵌套的paren匹配器将需要无限长的RE)。如果您正在处理该特定问题,则更容易尝试找到一些其他技术(例如,更长的“块结尾”字符串与),
匹配 - 如逗号 - 或使用递归解析器)。
答案 1 :(得分:1)
需要以匹配结束,直到结束变量' $'
() 27 % regexp {(.*?)\((.*?)\)(.*).*$} $a match sub1 sub2 sub3
1
() 28 % set sub3
,(xxxx)xxxx
() 29 % set sub1
substring1
() 30 % set sub2
substring2
() 31 % set sub3
,(xxxx)xxxx