Добавление дополнительной обратной косой черты к элементам списка TCL

У меня есть список, который выглядит так:

list1 = {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}

Когда я работаю с элементом списка один за другим, используя цикл foreach:

`foreach ele $list1 {
puts "$ele
}`

Я получаю следующий вывод:

a.b.c.d a.bb.ccd[0] a.bb.ccd[1]

Заметьте, что обратная косая черта пропадает(из-за языкового потока tcl).

Чтобы сохранить то же самое, я хочу добавить дополнительную обратную косую черту ко всем элементам list1, имеющим существующую обратную косую черту.

Я старался:

regsub -all {\} $list1 {\\} list1(Также пробовал двойные кавычки вместо фигурных скобок и других возможных испытаний).

Ничто не похоже на работу.

Есть ли способ убедиться, что $ ele сохраняет символы обратной косой черты внутри цикла foreach, так как мне нужны элементы с точно такими же символами для дальнейшей обработки.

PS Новичок в использовании regexp/regsub

2 ответа

Решение

Если ваши входные данные имеют обратную косую черту в том виде, в котором вы хотите сохранить, вам нужно немного поработать при преобразовании этих данных в список Tcl, или Tcl просто предположит, что вы использовали обратную косую черту как обычные метасимволы Tcl. Есть несколько способов сделать это; Вот мой личный фаворит, так как он логически выбирает именно те символы, которые нам нужны (непустые последовательности непробельных символов):

set input {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}
set items [regexp -all -inline {\S+} $input]
foreach item $items {
    puts $item
}

Как видно из вывода:

ABCD
a.bb.ccd\[0\]
a.bb.ccd\[1\]
....

это точно сохраняет обратную косую черту. (Кроме того, да, мне очень нравятся регулярные выражения. Особенно очень простые, как это.)

Как вы определили list1 это строка. когда list1 используется с foreach команда, то строка преобразуется в список. Помните, что списки в Tcl на самом деле представляют собой просто специально отформатированные строки, которые анализируются при преобразовании из строки в список. Когда элементы списка анализируются, обратные слеши удаляются в соответствии с обычными правилами синтаксического анализа Tcl. Существует несколько способов создания списков, содержащих символы, значимые для анализатора Tcl. Код ниже показывает два примера, противопоставленных вашему коду:

set list1 {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\]}
puts "list1 as a string"
puts $list1

puts "converting the list1 string to a proper list"
foreach ele $list1 {
    puts $ele
}

set list2 [list a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}]
puts "list2 build by the list command"
puts $list2

puts "list2, element by element"
foreach ele $list2 {
    puts $ele
}

set list3 {a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}}
puts "list3 build properly quoting each element"
puts $list3

puts "list3, element by element"
foreach ele $list3 {
    puts $ele
}

Запуск этого дает:

list1 as a string
a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\]
converting the list1 string to a proper list
a.b.c.d
a.bb.ccd[0]
a.bb.ccd[1]
list2 build by the list command
a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}
list2, element by element
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]
list3 build properly quoting each element
a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}
list3, element by element
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]

Ваш regsub попытка сработает, если вы замените каждый обратный слеш двумя обратными слешами, но правильное построение списка намного яснее.

Другие вопросы по тегам