Добавление дополнительной обратной косой черты к элементам списка 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
попытка сработает, если вы замените каждый обратный слеш двумя обратными слешами, но правильное построение списка намного яснее.