Строка tcl не работает с обратными ссылками на регулярные выражения
См. код ниже, в качестве примера, я пытаюсь найти использование regsub с backrefeence как средство выборочного использования string toupper
, Я не получаю то, что я ожидал.
Смотрите простой пример ниже (да, я знаю, что могу использовать string toupper $string 0 0
Однако это просто для демонстрации принципа на простом примере).
> puts [ regsub {^(.)} "min" "s\\1" ]
smin
> puts [ regsub {^(.)} "min" [ string toupper "\\1" ] ]
min
Как можно заметить, строка, применяемая к обратным ссылкам, не работает, но обратная ссылка может использоваться в операции двойных кавычек.
Я использую TCL вер. 8,6
1 ответ
string toupper
работает, но не делает то, что вы хотите; string toupper "\\1"
это просто строка \1
Итак regsub
не имеет большого эффекта. Проблема в том, что regsub
не имеет никакого способа "выполнить эту команду на сайтах замещения"; Я хотел исправить это в течение многих лет, но на самом деле никогда не делал этого (слишком много проектов для этого, чтобы выйти на первый план).
Вместо этого вам нужно regsub
в подстановке команды в строку, а затем subst
результат, но для того, чтобы сделать это, вы должны сначала сделать строку в противном случае безопасным для subst
с string map
, К счастью, это на самом деле довольно просто.
Я разделил это на части, чтобы вам было проще понять, что именно делает каждый этап:
set str "here is an example with \$dollars, \[brackets\] and \\backslashes"
# Quote all of Tcl's metacharacters; there's not that many
set safer [string map {[ \\[ ] \\] \\ \\\\ $ \\$} $str]
# Inject the command we want to run where we want to run it
set withsubst [regsub {^(.)} $safer {[string toupper {\1}]}]
# Perform the substitution
set result [subst $withsubst]