在Tcl中执行含美元符号的Perl命令时的转义问题
解决Tcl调用Perl时$符号转义问题
问题原因
Tcl会对命令替换([exec ...])中的$符号进行变量解析,你原命令里的$1被Tcl误认为是要替换的变量,因此报错no variable '1'。而错误地用{$1}转义会导致Perl收到的是{$1}字符串,无法识别为捕获组引用,自然无法正常工作。
可行解决方案
方案1:用Tcl大括号包裹Perl脚本(推荐)
Tcl的大括号{}内部会完全保留原始内容,不做任何变量或命令替换,是最可靠的转义方式。同时注意把原命令中的"替换为实际的双引号"(Perl无法识别HTML实体):
set varA [exec grep ^library $file | perl -pe {s/.*\(\s*"*(.*?)"*\s*\).*/$1/}]
方案2:在$前加反斜杠转义
如果坚持使用单引号包裹Perl脚本,需要给$加上反斜杠\,让Tcl跳过变量解析,将$1原样传递给Perl:
set varA [exec grep ^library $file | perl -pe 's/.*\(\s*"*(.*?)"*\s*\).*/\$1/']
方案3:将Perl脚本存入Tcl变量后调用
把Perl正则表达式单独存为变量,再传递给exec,可读性更好,也避免转义问题:
set perl_re {s/.*\(\s*"*(.*?)"*\s*\).*/$1/} set varA [exec grep ^library $file | perl -pe $perl_re]
内容的提问来源于stack exchange,提问作者David Peng
相关产品推荐
相关产品推荐

