TCL regsub использует совпадение RegEx в качестве индекса в ассоциированном массиве - PullRequest
1 голос
/ 11 октября 2019

Я хочу автоматически преобразовать URL-адреса, т.е.

Я пробовал следующий фрагмент кода в TCL

set loc "https://sc-uat.ct.example.com/sc/"

set envs(dev) "test"
set envs(uat) "beta"
set envs(qa) "demo"

puts $envs(uat)
regsub -nocase {://.+-(.+).ct.example.com} $loc {://inv[$envs(\1)].example.com} hostname

puts "new location = $hostname"

Но результат: новое местоположение =https://inv[$envs(uat)].example.com/sc/

Похоже, что [$ envs (uat)] НЕ оценивается и заменяется далее реальным значением. Любые подсказки будут оцененыЗаранее спасибо

1 Ответ

1 голос
/ 11 октября 2019

Но результат: новое местоположение = https://inv[$envs(uat)].example.com/sc/ Кажется, что [$ envs (uat)] продвигается дальше.

Вы хотели сказать:[$envs(uat)] оценивается ли не далее?

Это связано с тем, что из-за фигурных скобок в {://inv[$envs(\1)].example.com} строка вставки берется буквально и не подвергается замене переменных или команд,Кроме того, вам не нужна подстановка команд и переменных ([$envs(\1)]), только одна из них: $envs(\1) или [set envs(\1)].

Чтобы преодолеть это, вы должны обработать строку, обработанную regsub, далее черезsubst:

set hostname [subst -nocommands -nobackslashes [regsub -nocase {://.+-(.+).ct.example.com} $loc {://inv$envs(\1).example.com}]]

Предложения по улучшению

Я советую избегать использования subst в этом контексте, потому что даже если вы ограничены, вы можете столкнуться с конфликтами с символами,Tcl в ваших именах хостов (например, в скобках в разделах полномочий IPv6). Либо вам нужно санировать строку loc ранее, либо лучше работать с диапазонами строк, например:

if {[regexp -indices {://(.+-(.+)).ct.example.com} $loc _ replaceRange keyRange]} {
    set key [string range $loc {*}$keyRange]
    set sub [string cat "inv" $envs($key)]
    set hostname [string replace $loc {*}$replaceRange $sub]
}
...