如何在TCL中匹配整个单词? regexp" \\ msub1 \\ M" sub1_ex

时间:2012-01-03 05:02:38

标签: regex word tcl

请帮我解决这个问题......

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。

2 个答案:

答案 0 :(得分:0)

好吧,我想我终于设法解析了这个问题。

第一个问题是“sub”是“sub1”的子串,它们都是“sub1_ex”的子串。

第二个问题是,正则表达式引擎方面的“单词”是匹配类\w的相邻字符的连续块,其中包括字母数字和下划线(请参阅this),所以如果你使用\m\M来锚定模式“sub1”,字符串“sub1_ex”将不匹配,因为“1”和“_”之间没有字边界。

接下来要做什么确实取决于你的用例,不幸的是我并没有得到它。将var2更改为sub\M可能会修复它,但我不确定它是您想要的。

答案 1 :(得分:0)

你遇到的问题是字符类包含下划线字符,因此特殊的“字的开头/结尾”模式对你不起作用。

部分解决方案是使用更精细的匹配:

regexp "\\m${var1}(?!\[a-zA-Z0-9\])" $var3

这适用于一个单词的结尾,但不是在开头(Tcl中使用的RE引擎不支持任何类型的lookbehind约束)。因此,转换匹配的字符串实际上更简单:

regexp "\\m$var1\\M" [string map {"_" " "} $var3]

如果您尝试查找的字符串不包含下划线,那将会正常工作。我猜你的情况确实如此。如果没有,你必须使用真正的技巧并插入一些非常罕见的角色作为替代品:

set mapping {"_" "\ufffd"};   # Unicode replacement char!
regexp "\\m[string map $mapping $var1]\\M" [string map $mapping $var3]