TCL regexp未返回预期匹配:文件名电压数值提取缺失问题
问题分析与解决方案
你的问题出在正则表达式的匹配逻辑上——当前的_(\dp\d{3})v_会消耗掉匹配字符串前后的下划线,导致中间的电压组被跳过。
具体原因
正则引擎在匹配时,会从左到右扫描字符串,一旦匹配到_0p500v_,它会把这个子串(包括结尾的下划线)标记为已匹配区域。接下来引擎会从这个区域的下一个字符(也就是0p530v的第一个0)开始继续扫描,而中间的0p530v前面的下划线已经被前一个匹配消耗了,自然找不到符合_(\dp\d{3})v_的模式,所以直接跳过了中间组,只匹配到第一组和第三组。
两种修复方案
方案1:使用正向预查避免消耗下划线
把正则改成正向预查的形式,这样结尾的下划线只会被用来判断,不会被消耗,让下一次匹配可以复用这个下划线:
set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat" regexp -all -inline {_(\dp\d{3})v(?=_)} $data
执行后会返回:
_0p500v 0p500 _0p530v 0p530 _0p550v 0p550
如果需要保留匹配结果中的结尾下划线,也可以调整为_(\dp\d{3})v(?=_|$),这样同时兼容字符串结尾的情况。
方案2:匹配边界(开头/下划线)和结束边界(下划线/结尾)
这种方法更通用,不管电压组在文件名的哪个位置(开头、中间、结尾)都能匹配到:
set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat" regexp -all -inline {(?:^|_)(\dp\d{3})v(?:_|$)} $data
执行后会得到你预期的结果:
_0p500v_ 0p500 _0p530v_ 0p530 _0p550v_ 0p550
这里的(?:^|_)表示匹配字符串开头或者下划线(非捕获组,不会出现在结果里),(?:_|$)表示匹配下划线或者字符串结尾,完美解决了重叠下划线的问题。
内容的提问来源于stack exchange,提问作者Gert Gottschalk
相关产品推荐
相关产品推荐

