请帮我解决这个...如何在TCL中匹配整个单词?正则表达式 “\ \ msub1 M” sub1_ex
set var1 sub1
set var2 sub
set var3 sub1_ex
我想匹配$var1
和$var3
,而不是$var2
即
regexp $var1 $var3
应为1; regexp $var2 $var3
应该是0;但得到1
我也试过
regexp "\\m$var1\\M" $var3
,但得到0
请帮我解决这个...如何在TCL中匹配整个单词?正则表达式 “\ \ msub1 M” sub1_ex
set var1 sub1
set var2 sub
set var3 sub1_ex
我想匹配$var1
和$var3
,而不是$var2
即
regexp $var1 $var3
应为1; regexp $var2 $var3
应该是0;但得到1
我也试过
regexp "\\m$var1\\M" $var3
,但得到0
好吧,我想我终于成功地解析问题。
第一个问题是“sub”是“sub1”的子字符串,它们都是“sub1_ex”的子字符串。
的第二个问题是,在正则表达式引擎的术语“字”是匹配类\w
其中既包括字母数字和下划线(参见this)相邻字符的contigous块,因此如果使用\m
和\M
锚定模式“sub1”,字符串“sub1_ex”不匹配,因为“1”和“_”之间没有字边界。
接下来要做什么确实取决于你的使用情况,不幸的是我不太明白。将var2
更改为sub\M
可能会解决它,但我不确定这是您想要的。
你得到的问题是,单词字符类包含下划线字符,所以特殊的“在字的开始/结束”模式不适合你。
一个部分解决方案是使用一种更精细的匹配:
regexp "\\m${var1}(?!\[a-zA-Z0-9\])" $var3
此作品在词的结尾,而不是在开始(Tcl中使用的RE引擎不支持任何形式的的后视限制)。因此,它实际上是简单的改造对字符串相匹配:
regexp "\\m$var1\\M" [string map {"_" " "} $var3]
这将正常工作提供你想找到不包括下划线的字符串。我想你的情况确实如此。如果没有,你必须使用一个真正伎俩,并插入一些真是难得字符作为替代:
set mapping {"_" "\ufffd"}; # Unicode replacement char!
regexp "\\m[string map $mapping $var1]\\M" [string map $mapping $var3]
另外要注意,在字符串中RE元字符正在搜索会出现问题。 – 2012-01-03 10:12:58