我在TCL中有以下代码:
regexp "\[00]\[00].info.age\\s*=\\s*26" "[00][00].info.age = 26"
但它不匹配,问题是什么以及如何修复它?
答案 0 :(得分:2)
如我previous answer中所述,请使用大括号并避免所有双重转义:
% 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
答案 1 :(得分:1)
首先,在第二个参数中,你应该转义[
放入以下字符串"\[00]\[00].info.age = 26"
,否则Tcl将执行命令执行并返回无效命令名“00”< / em>的
然后,问题在于您使用引号"
对模式进行分组,但在引号中会发生替换。因此,转义 [
可以避免命令执行,但会以简单的方式传递给regexp
命令,而regexp "\\\[00]\\\[00].info.age\\s*=\\s*26" "\[00]\[00].info.age = 26"
命令又将其视为bracked表达式的开头。
您有两个选择,第一个是以下
\\
非常丑陋,但完成工作:在模式中,第一个\
被单个\[
替换,以下[
被\[00]\[00].info.age\s*=\s*26
替换为pattern成为这个文字字符串
regexp {\[00]\[00].info.age\s*=\s*26} "\[00]\[00].info.age = 26"
另一种方法是用花括号替换模式中的引用字符,以避免解析器替换步骤:
\
您还必须从每个\\s
中删除一个regexp
,因为您不再需要将其撤消。
编辑:一点解释
解析器在执行"
命令之前执行替换。
解析器会看到分组字符"..."
,因此它会在其中执行替换。在[...]
内,一对耦合[...]
是命令执行,因此调用内部命令并且其结果替换[
字符串。
要避免这种替换,您需要使用\[
转义regexp
。
之后,解析器完成了它的工作,它是[...]
的转向,它被执行。
如果您传递给它的模式包含[
组,那么您将为其提供一个括号表达式,这是一组可供选择的字符。
你不希望这样,因为你必须匹配文字 regexp
,所以你必须告诉\
放弃它的特殊含义:为此,你必须转义它,在它前面放一个反斜杠\[
,即regexp
。
然后,您的代码必须将反斜杠后跟左括号传递给\\
,但两者都是Tcl的特殊字符,并且它们具有对Tcl解析器有特殊意义,首先调用它。
因此,要删除反斜杠的特殊含义,Tcl解析器必须看到两个反斜杠:这些是您在模式中看到的前两个反斜杠,{{ 1}};要删除左括号的特殊含义,Tcl解析器必须通过反斜杠看到转义:这是您在模式中看到的第三个反斜杠,{{1} }。
我希望这更清楚:)