我尝试使用regsub
将所有未加盖的"
替换为}
。我得到了以下内容。
% set st {hello "hi this athat afsd\" adsfasdf"}
% regsub -all {(?!\\)\"} $st \}
hello }hi this athat afsd\} adsfasdf}
我想要的是什么
hello }hi this athat afsd\" adsfasdf}
。请告诉我出了什么问题。
答案 0 :(得分:1)
你必须使用反向引用来实现相同的目标。
set st {hello "hi this athat afsd\" adsfasdf"}
puts $st
regsub -all {([^\\])"} $st \\1\} result
puts $result
<强>输出:强>
hello "hi this athat afsd\" adsfasdf"
hello }hi this athat afsd\" adsfasdf}
文档:regsub man page&amp; regexp_how_to
答案 1 :(得分:1)
嗯,你正在使用的正则表达式并没有真正按照你的想法去做。从字面上看,它会尝试匹配(?!\)"
(双引号与前面包含一个反斜杠的负前瞻)。
让我们试着详细了解事情是如何运作的。我将在比赛前后采样,增加空格以使其更清晰。
a f s d \ "
^
这里引擎向前看并看到反斜杠。由于前瞻性为负,匹配失败,因此继续使用字符串。
a f s d \ "
^
现在它通过了反斜杠,它试图再次进行匹配。前方没有反斜杠,因此负前瞻不会阻止匹配。接下来,正则表达式尝试匹配成功的双引号。
通常,你需要一个 lookbehind 来做你想要做的事情,因为前瞻不能检查它已经传递的东西,但是负面的后视就是这样。不幸的是,tcl不支持lookbehinds(并且实际上不需要一个,因为已经有更高效的变通方法)所以最好匹配转义的引号,但是单独处理它们(这里将它们放回原来就像它们一样均)。
例如,您可以使用类似
的内容 regsub -all {(\\")|"} $st {\1} result
答案 2 :(得分:1)
如果您要重新考虑使用regsub
,使用string map
命令可以更简单地进行此转换:
string map {\\\" \\\" \" \}} $st
它的要点是&#34;将\"
替换为\"
(即保持不变),但将"
替换为}
&#34;。它看起来很尴尬,因为(在这种情况下)每个角色都需要被转义,所以\"
变成\\\"
等等,但它真的非常简单。
文档:string