典型的なユースケースは、正規表現にユーザー入力を含める必要がある場合です。正規表現で特別な意味を持つ文字 (つまり、Perl の「ダーティ ダース」) はエスケープする必要があります。Perl はこれを行うための "quotemeta" 機能を提供します: 内挿変数を と にカプセル化するだけ\Q
です\E
。しかし、Tcl にはそのような機能はありません (このページによると、ARE を使用しても)。
Tcl に quotemeta の適切な (厳密な) 実装はありますか?
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 と同じように機能すると思います。)
解決策を提案しますが、それが正しいとは確信できません。
#
# 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
}