在Tcl中实现“quotemeta”\ Q ... \ E?

时间:2012-07-11 21:54:37

标签: regex tcl pcre quotemeta

典型的用例是当正则表达式需要包含用户输入时。在正则表达式中具有特殊含义的字符(即Perl中的“脏打”)需要被转义。 Perl提供了“quotemeta”功能:只需将插值变量封装在\Q\E中。但是Tcl没有提供这样的功能(并且根据this page,即使是ARE)。

在Tcl中有一个很好的(严格的)quotemeta实现吗?

2 个答案:

答案 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
}