典型的用例是当正则表达式需要包含用户输入时。在正则表达式中具有特殊含义的字符(即Perl中的“脏打”)需要被转义。 Perl提供了“quotemeta”功能:只需将插值变量封装在\Q
和\E
中。但是Tcl没有提供这样的功能(并且根据this page,即使是ARE)。
在Tcl中有一个很好的(严格的)quotemeta实现吗?
答案 0 :(得分:3)
Perl的quotemeta
函数只是用反斜杠替换每个非单词字符(即26个小写字母,26个大写字母,10个数字和下划线以外的字符)。这是过度的,因为并非所有非单词字符都是正则表达元字符,但它简单而安全,因为转义不需要转义的非单词字符是无害的。
我相信这种实施是正确的:
proc quotemeta {str} {
regsub -all -- {[^a-zA-Z0-9_]} $str {\\&} str
return $str
}
但是感谢glenn的评论,这个更好,至少对于现代版本的Tcl(\W
匹配任何在Tcl 8.0.5之后的某个时间开始的非单词字符):
proc quotemeta {str} {
regsub -all -- {\W} $str {\\&} str
return $str
}
(我假设Tcl的正则表达式与Perl类似,所以这将在Tcl中完成与在Perl中相同的工作。)
答案 1 :(得分:1)
我会提出一个解决方案,但我不相信这是正确的。
#
# notes
#
# - "[]" has to appear in the beginning of a character class
# - "-" has to come last in a character class
# - "#" is not special, but anticipating the x modifier...
# - "-" is not special, but anticipating interpolation within "[]"...
# - "/" is not special in Tcl
#
proc quotemeta {str} {
regsub -all -- {[][#$^*()+{}\|.?-]} $str {\\\0} str
return $str
}