0

我在 TCL 中有以下代码:

regexp "\[00]\[00].info.age\\s*=\\s*26" "[00][00].info.age = 26"

但它不匹配,是什么问题以及如何解决?

4

2 回答 2

2

正如我之前的回答中提到的,使用大括号并避免所有双重转义:

% set str "\[00]\[00].info.age = 26"
[00][00].info.age = 26
% regexp {\[00]\[00].info.age\s*=\s*26} $str
1

否则,您将不得不双重转义(在这种情况下为三次转义?因为[]用于调用命令。我不知道如何调用它......):

% set str "\[00]\[00].info.age = 26"
[00][00].info.age = 26
% regexp "\\\[00]\\\[00].info.age\\s*=\\s*26" $str
1
于 2013-08-12T09:40:52.823 回答
1

首先,在第二个参数中,你应该[将后面的字符串 ,转义"\[00]\[00].info.age = 26",否则 Tcl 将执行命令并返回无效的命令名称 "00"

然后,问题是您使用引号"对模式进行分组,但是在引号中会发生替换。因此,您的转义 [避免命令执行,而是作为简单的括号传递给regexp命令,而命令又将其视为括号表达式的开头。

您有两个选择,第一个是以下

regexp "\\\[00]\\\[00].info.age\\s*=\\s*26" "\[00]\[00].info.age = 26"

相当丑陋但可以完成工作:在模式中,第一个\\被替换为 single \,以下\[被替换为 a[并且模式变成了这个文字字符串

\[00]\[00].info.age\s*=\s*26

另一种方法是用花括号替换模式中的引号字符,以避免解析器替换步骤:

regexp {\[00]\[00].info.age\s*=\s*26} "\[00]\[00].info.age = 26"

您还必须\从每个中删除一个,\\s因为您不再需要逃避它。


编辑:一点解释

解析器在执行命令之前regexp执行替换。

解析器看到分组字符",因此它在其中执行替换。在内部"...",一对耦合[...]是一个命令执行,因此调用内部命令并将其结果替换为[...]字符串。

为避免这种替换,您需要转义[using \[

之后,解析器完成了它的工作,轮到regexp执行了。

如果你传递给它的模式包含一个[...]组,你给它一个括号表达式,这是一组可供选择的字符。

你不希望这样,因为你必须匹配一个文字 [,所以你必须告诉regexp删除它的特殊含义:要做到这一点,你必须通过在它前面放置一个反斜杠来转义\它,即\[.

然后,您的代码必须传递一个反斜杠,后跟一个左括号regexp但对于 Tcl 来说,这两个字符也是特殊字符,并且它们对首先调用的 Tcl 解析器具有特殊含义。

因此,要删除反斜杠的特殊含义,Tcl 解析器必须看到两个反斜杠:这是您在模式中看到的前两个反斜杠\\;要删除左括号的特殊含义,Tcl 解析器必须看到它被反斜杠转义:这是您在模式中看到的第三个反斜杠\[ .

我希望这更清楚:)

于 2013-08-12T09:46:57.360 回答