как отфильтровать имя иерархии, имеющее только n уровень иерархии, из списка имен иерархии, используя lsearch и regexp - PullRequest
0 голосов
/ 26 июня 2019

hierarchy_names = a/b/c a x d/e f/g h/i/j/k l/m/n o/p Я пытаюсь отфильтровать 2 level имя_иерархии, т. Е. d/e f/g и o/p из списка Иерархий_имений, имеющих несколько уровней Иерархии_имений.

Я пыталсяlsearch но проблема в том, что он возвращает совпадения с уровнем иерархии, большим или равным 2, т. Е. a/b/c d/e f/g h/i/j/k l/m/n o/p, но не точно равным 2, т. Е. d/e f/g o/p из-за алгоритма возврата элемента, если это contains шаблон.Я также пробовал regexp, но проблема в том, что он возвращает 2-уровневые иерархические имена вместе с частичной 2-уровневой иерархией, присутствующей в более высоких иерархических именах, то есть a/b d/e f/g h/I j/k l/m

set hier {a/b/c a x d/e f/g h/i/j/k l/m/n}
puts [lsearch -all -inline -regexp $hier {\w+/\w+}]
puts [regexp -all -inline {\w+/\w+} $hier]

d/e f/g o/p

Ответы [ 3 ]

1 голос
/ 26 июня 2019

Я бы использовал другой инструмент в арсенале Tcl (при условии, что у вас Tcl 8.6).

set hierarchy_names {a/b/c a x d/e f/g h/i/j/k l/m/n o/p}
set filtered [lmap n $hierarchy_names {
    if {[llength [file split $n]] != 2} continue
    string cat $n
}]
puts $filtered
# d/e f/g o/p

Используется lmap для применения короткого сценария к каждому элементу списка. Результатом списка является либо сигнал continue (который пропускает элемент), либо элемент; проверка выполняется путем просмотра длины списка вывода file split.

1 голос
/ 27 июня 2019

как насчет регулярных выражений?

Вы можете придумать регулярное выражение, подобное этому:

 (?:\s+|^)(\w+/\w+)(?=\s+|$)
  • Первая группа без захвата привязывает шаблон соответствияв начале строки или элемента списка.
  • Вторая группа захвата фактически сохраняет то, что вы ищете.
  • Позитивный прогноз гарантирует, что шаблон совпадения не станет слишком жадным (т.е., переходит в следующий элемент списка).

Это вернет четный список совпадений с подстатьем в нечетных позициях.Чтобы отфильтровать их, вы можете использовать [dict values] или явный [foreach], например.

dict values [regexp -all -inline -- {(?:\s+|^)(\w+/\w+)(?=\s+|$)} $hier]
1 голос
/ 26 июня 2019

Якоря линии могут помочь вам в этом случае.

% lsearch -all -inline -regexp $hier {^\w+/\w+$}
d/e f/g
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...