在tcl(版本8.4)中,我想分割一个这样的字符串:
"param1=>someval param2=>anotherval"
分为两个列表,例如:
params = param1 param2
values = someval anotherval
如果是单个分隔符,例如=
,我可以使用split
命令。是否有双字符分隔符的等价物?
答案 0 :(得分:2)
您可以使用regexp
来获取参数/值对,例如:
set text "param1=>someval param2=>anotherval"
set params [list]
set values [list]
foreach {all param value} [regexp -all -inline -- {(\S+)=>(\S+)} $text] {
lappend params $param
lappend values $value
}
puts $params
puts $values
# => param1 param2
# => someval anotherval
正则表达式(\S+)
捕获一系列非空格字符(包括非换行符和类似字符),这样如果您的参数和值包含空格,则必须修改该模式(请参阅{{3 }})。如果其中没有空格,那么上述内容应该没有任何问题。
如果您想分割两次,即一次在空格上然后在=>
上,那么我建议在那里使用re syntax:
set text "param1=>someval param2=>anotherval"
set list [split $text]
set params [list]
set values [list]
foreach elem $list {
set newElem [string map {=> \0} $elem]
set pair [split $newElem \0]
lappend params [lindex $pair 0]
lappend values [lindex $pair 1]
}
puts $params
puts $values
# => param1 param2
# => someval anotherval
在这里,我们将=>
上的字符替换为null \0
(这是一个不太可能出现在普通字符串中的字符)然后拆分为null。
答案 1 :(得分:2)
scan
来实现。
set input "param1=>someval param2=>anotherval"
foreach element $input {
if { [ scan $element {%[^=>]=>%s} p v ] == 2 } {
puts $p
puts $v
} else {
puts "Scan failed for param and value. :("
}
}
在这里,我利用了Tcl的列表实现,因为它充当了一个用空格分隔的列表。如果输入没有空格,则必须自定义scan
命令。
答案 2 :(得分:1)
尝试使用tcllib:
中的textutil包http://tcllib.sourceforge.net/doc/textutil.html
它有一个名为::textutil::splitx
的程序可以满足您的需求。
答案 3 :(得分:1)
你可以这样做:
set text "param1=>someval param2=>anotherval"
foreach {p v} [string map {=> { }} $text] {
lappend params $p
lappend values $v
}
set params
# => param1 param2
set values
# => someval anotherval
通过用空格替换=>
子串,可以获得一个偶数大小的列表,其中每个其他元素都是参数名称字符串,而每个其他元素都是一个值字符串。这是假设参数名称或值中没有任何空格。