带有转义字符的regsub的异常行为

时间:2019-08-08 16:40:25

标签: escaping tcl

当我给它包含转义字符的字符串时,TCL regsub命令的行为似乎很奇怪。

我已经使用自动预期功能从要自动测试的应用程序中捕获了一系列屏幕显示。我没有尝试将其输出用作单个块,而是尝试将生成的脚本转换为一系列字符串以提高可维护性。我使用vi来创建了一系列片段,然后一次读取一个片段,并将其用作与期望值匹配的片段。我确实必须进行一些替换(例如,“ ^ [”变为“ ESC”),但是我必须对片段5进行处理,因此该想法通常是可行的。不幸的是,在模式“ xxxx \ [[xxxx”(x是其他字符)中,用“ [”替换了“ \ [”令我感到吃惊。

我已经编写了一个Tcl ascii字符串转储过程,并且在这里使用它。

SSPT245612  TK29078
SSPT245612  TK29195
SSPT245612  TK29199
SSPT245613  TK16330
SSPT245613  TK16331
SSPT245614  TK16330
SSPT245614  TK16331
SSPT245614  TK16373
SSPT245614  TK16737
SSPT245614  TK18008
SSPT245615  TK16916
SSPT245615  TK16917
SSPT245615  TK16918
SSPT245617  TK18329
SSPT245618  TK11309
SSPT245618  TK11320
SSPT245618  TK20245
SSPT245618  TK20454
SSPT245618  TK29725
SSPT245637  TK12137
SSPT245637  TK18815
SSPT245637  TK19088
SSPT245637  TK19090
SSPT245637  TK19232
SSPT245637  TK23330
SSPT245637  TK23331
SSPT245637  TK23947
SSPT245637  TK23948
SSPT245637  TK24006
SSPT245637  TK25505
SSPT245637  TK25506
SSPT245637  TK25507
SSPT245637  TK25508
SSPT245642  TK28365
SSPT245642  TK28366
SSPT245642  TK28372
SSPT245642  TK28373
SSPT245643  TK15293
SSPT245644  TK16330
SSPT245644  TK16331
SSPT245645  TK16330
SSPT245645  TK16331
SSPT245650  TK24811
SSPT245650  TK25744
SSPT245653  TK16330
SSPT245653  TK16331
SSPT245659  TK18333
SSPT245659  TK27345
SSPT245659  TK27346
SSPT245659  TK27347
SSPT245659  TK27385
SSPT245660  TK11300
SSPT245660  TK20066
SSPT245661  TK19179
SSPT245662  TK13738
SSPT245662  TK27514
SSPT245662  TK31244
SSPT245663  TK15484
SSPT245663  TK20167
SSPT245664  TK13981
SSPT245665  TK15293
SSPT245666  TK16330
SSPT245666  TK16331
SSPT245667  TK19688
SSPT245668  TK13331
SSPT245669  TK16330

在以上系列中,我首先检查是否可以创建2个字符的模式“ \ [”。然后,我创建一个模式,它是我的实际问题字符串“ a \ [[z””的缩写形式。然后,我将regexp和测试字符串提交给regsub,希望将“ \ [”字符替换为单个“ Z”。如您所见,发生了两次替换(而不是一次替换),并且字符2出现意外的“ \”!

任何启发都非常欢迎。 (我已经花了很多时间(包括编写ascii dump proc!),但是我却一无所获...

最好的祝福,艾伦

1 个答案:

答案 0 :(得分:1)

这是大多数语言中正则表达式通常的工作方式。

如果您使用原始字符串,则regsub命令将如下所示:

regsub -all {\[} {a\[[z} "Z" newstring

在正则表达式中,\[代表文字字符[\转义了元字符[,否则就指示字符类的开始)。

如果要替换字符串\[,则需要替换反斜杠和右括号,用正则表达式表示为:\\\[,因此, regsub变为:

regsub -all {\\\[} {a\[[z} "Z" newstring
puts $newstring
# aZ[z

如果要使用引号,则需要做更多的转义操作。 \\\[中的每个字符都需要转义,基本上,您需要为每个字符添加一个反斜杠:

regsub -all "\\\\\\\[" "a\\\[\[z" "Z" newstring
puts $newstring
# aZ[z

或者您可以使用string map

string map {{\[} {Z}} {a\[[z}

string map {"\\\[" {Z}} "a\\\[\[z"

应该做