如何使用lsearch和regexp从等级名称列表中过滤仅具有n个等级的等级名称

时间:2019-06-26 10:04:36

标签: tcl

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/go/p

我尝试了lsearch,但是问题是,它返回了具有大于或等于2的等级的匹配项,即a/b/c d/e f/g h/i/j/k {{ 1}} l/m/n但不完全等于2,即o/p d/e f/g,因为它的算法返回元素是否为o/p模式。 我也尝试过contains,但是问题是,它会返回2层archive_names以及在较高层archive_names中存在的部分2层hierarchy,即regexp a/b d/e {{1 }} 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

3 个答案:

答案 0 :(得分:1)

在这种情况下,行锚可能会对您有所帮助。

% lsearch -all -inline -regexp $hier {^\w+/\w+$}
d/e f/g

答案 1 :(得分:1)

我会在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的输出列表的长度来完成测试。

答案 2 :(得分:1)

  

正则表达式是什么?

您可以设计这样的正则表达式:

 (?:\s+|^)(\w+/\w+)(?=\s+|$)
  • 第一个非捕获组将匹配模式锚定在字符串或列表元素的开头。
  • 第二个捕获组实际上存储了您所需要的东西。
  • 积极的前瞻性确保匹配模式不会变得过于贪婪(即流入后续列表元素)。

这将返回一个偶数匹配项列表,其中子匹配项位于奇数位置。要过滤掉它们,您可以使用[dict values]或明确的[foreach],例如。

dict values [regexp -all -inline -- {(?:\s+|^)(\w+/\w+)(?=\s+|$)} $hier]