Строка 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]
Другие вопросы по тегам