试图从字符串中提取模式
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
我有一个像
这样的字符串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