2

典型的なユースケースは、正規表現にユーザー入力を含める必要がある場合です。正規表現で特別な意味を持つ文字 (つまり、Perl の「ダーティ ダース」) はエスケープする必要があります。Perl はこれを行うための "quotemeta" 機能を提供します: 内挿変数を と にカプセル化するだけ\Qです\E。しかし、Tcl にはそのような機能はありません (このページによると、ARE を使用しても)。

Tcl に quotemeta の適切な (厳密な) 実装はありますか?

4

2 に答える 2

3

Perl のquotemeta関数は、すべての非単語文字 (つまり、26 個の小文字、26 個の大文字、10 個の数字、およびアンダースコア以外の文字) を単純にバックスラッシュに置き換えます。すべての非単語文字が正規表現メタ文字であるとは限らないため、これはやり過ぎですが、エスケープする必要のない非単語文字をエスケープすることは無害であるため、単純で安全です。

この実装は正しいと思います:

proc quotemeta {str} {
    regsub -all -- {[^a-zA-Z0-9_]} $str {\\&} str
    return $str
}

しかし、glenn のコメントのおかげで、少なくとも最新バージョンの Tcl では、これの方が優れています ( \WTcl 8.0.5 からしばらくしてから始まる単語以外の文字に一致します)。

proc quotemeta {str} {
    regsub -all -- {\W} $str {\\&} str
    return $str
}

(Tcl の正規表現は Perl の正規表現と十分に似ているため、Tcl でも Perl と同じように機能すると思います。)

于 2012-07-11T22:06:29.383 に答える
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
}
于 2012-07-11T21:57:55.960 に答える