试图从字符串中提取模式

Trying to extract pattern out of string

我有一个像

这样的字符串
set arr_set(variable.abc) {12,13}
set arr_set(variable.def) {15,16}
set arr_set(dont_care)    {0,0}

其中arr_set是一个数组集合,variable_abc是其中的一个元素。我将所有这些信息存储在一个文件中。我想做的是,阅读每一行,无论我在哪里看到 "variable.",我都会阅读它指向的内容,就像第一种情况一样,它指向 abc,然后是 def .

我写了这个脚本,但它显然没有存储信息。

regexp -nocase {^\s*set arr_set[(]variable\s*.\s*(.*)$} $lines match tag value

其中 lines 是包含

的字符串
set arr_set(variable.abc) {12,13}

我不知道这里缺少什么正则表达式。谁能看一下?

分解你的正则表达式:

^\s*set arr_set[(]variable\s*.\s*(.*)$
  • ^ : 行首锚点
  • \s* :零个或多个 spaces
  • 设置arr_set[(]变量:完全匹配此文本
  • \s* :零个或多个 spaces
  • 。 : 任意字符
  • \s* :多个 spaces
  • 中的零个
  • (.*) : 其余数据

您的正则表达式没有单独的标记和值组,但从您的代码来看,您似乎希望将它们分开。您有额外的 space 匹配项与您的数据不匹配。

set lines {set arr_set(variable.abc) {12,13}}
regexp -nocase {\(variable\.([^)]*)\)\s*(.*)} $lines match tag value
puts "$tag $value"

regexp -nocase {^\s*set\s*arr_set\(variable\.([^)]*)\)\s*(.*)} $lines match tag value

细分:

\(variable\.([^)]*)\)\s*(.*)
  • \(变量\. : 完全匹配此文本
  • ( : 开始组(标签)
  • [^)]* :零个或多个不是右括号的字符
  • ) : 结束组(标签)
  • \) : 右括号(完全匹配)
  • \s* :零个或多个 spaces
  • (.*) :其余数据(值)

(Glenn Jackman 在评论中提醒我 array names 可以对 select 名称采用 glob 模式。由于该功能在这种情况下显着简化了代码,因此我将我的回答重写为使用它。)

如果你有命令

set arr_set(variable.abc) {12,13}
set arr_set(variable.def) {15,16}
set arr_set(dont_care)    {0,0}

在您 source 的文件中,您可以使用它来获取 tag-value 对的列表:

lmap name [array names arr_set variable.*] {
    set tag [lindex [split $name .] 1]
    list $tag $arr_set($name)
}

# => {abc 12,13} {def 15,16}

(如果您不需要该值,请使用 set tag 而不是 list $tag $arr_set($name)

对于 Tcl 8.5 及更早版本,这也是相同的(将结果存储在 res 中):

set res {}
foreach name [array names arr_set variable.*] {
    set tag [lindex [split $name .] 1]
    lappend res [list $tag $arr_set($name)]
}

(如果您不需要该值,请使用 lappend res $tag 而不是 lappend res [list $tag $arr_set($name)]

请注意,此解决方案仅在数组名称 selection 可以表示为 glob 模式时才有效。在无法做到这一点的情况下,仍然需要按照以下思路进行解决:

lmap name [array names arr_set] {
    lassign [split $name .] prefix tag
    if {$prefix in {foo bar baz}} {
        list $tag $arr_set($name)
    } else {
        continue
    }
}

文档:array, continue, foreach, if, lappend, lassign, lindex, list, lmap, lmap replacement, set, source, split