我在 TCL 中有以下代码:
regexp "\[00]\[00].info.age\\s*=\\s*26" "[00][00].info.age = 26"
但它不匹配,是什么问题以及如何解决?
正如我之前的回答中提到的,使用大括号并避免所有双重转义:
% 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
首先,在第二个参数中,你应该[
将后面的字符串 ,转义"\[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 解析器必须看到它被反斜杠转义:这是您在模式中看到的第三个反斜杠,\[
.
我希望这更清楚:)