Удалить элементы с расширением точки из списка, используя регулярное выражение или сопоставление строк
Я новичок в Tcl. У меня есть список, как это:
set list1 {
dir1
fil.txt
dir2
file.xls
arun
baskar.tcl
perl.pl
}
Из этого списка я хочу только такие элементы, как:
dir1
dir2
Арун
Я попробовал regexp
а также lsearch
но не повезло.
Способ 1:
set idx [lsearch $mylist "."]
set mylist [lreplace $mylist $idx $idx]
Способ 2:
set b [regsub -all -line {\.} $mylist "" lines]
3 ответа
Метод 1 будет работать, если вы сделали это правильно. lsearch
по умолчанию возвращает один результат, а критерии поиска принимают шаблон глобуса. С помощью .
будет искать только элемент, равный .
, Тогда вам понадобится петля для lreplace
:
set idx [lsearch -all $list1 "*.*"]
foreach id [lsort -decreasing $idx] {
set list1 [lreplace $list1 $id $id]
}
Сортировка по убыванию важна, потому что индекс элементов будет меняться при удалении элементов (также обратите внимание, что вы использовали неверное имя переменной в своих фрагментах кода).
Метод 2 также будет работать, если вы используете правильное регулярное выражение:
set b [regsub -all -line {.*\..*} $list1 ""]
Но в этом случае вы, вероятно, захотите урезать результаты. .*
будет соответствовать любым символам, кроме новой строки.
Я бы наверное использовал lsearch
вот так, что исключает необходимость замены:
set mylist [lsearch -all -inline -not $list1 "*.*"]
Также можно отфильтровать список непринятых элементов, используя lmap
(или явный цикл с использованием foreach
):
lmap el $list1 {if {[string first . $el] >= 0} {continue} else {set el}}
Смотрите также связанное обсуждение по фильтрации списков, например, Использование `lmap` для фильтрации списка строк.
Команда lsearch имеет много опций, некоторые из которых могут помочь сделать эту задачу довольно простой:
lsearch -all -inline -not $list1 *.*