在Tcl中处理引用字符串中的逗号

时间:2011-01-10 19:16:59

标签: regex csv tcl

我在Tcl中使用以下行来解析以逗号分隔的字段行。可以引用某些字段,以便它们可以包含逗号:

set line {12,"34","56"}
set fresult [regsub -all {(\")([^\"]+)(\",)|([^,\"]+),} $line {{\2\4} } fields]
puts $fields
{12} {34} "56"

(引用最后一个字段而不是括号,这有点奇怪,但这不是问题)

但是,当引号中有逗号时,它不起作用:

set line {12,"34","56,78"}
set fresult [regsub -all {(\")([^\"]+)(\",)|([^,\"]+),} $line {{\2\4} } fields]
puts $fields
{12} {34} "{56} 78"

我希望: {12} {34} {56,78}

我的正则表达式是否有问题,或者有什么东西正在进行?

4 个答案:

答案 0 :(得分:5)

我想到的一个选项是在TclLib中使用CSV功能。 (没有理由重新发明轮子,除非你必须......)

http://tcllib.sourceforge.net/doc/csv.html

文档摘录

  

:: csv :: split? - 替代?线   {sepChar,} {delChar“}转换为   将CSV格式的行转换为列表   行中包含的值。该   用于分隔值的字符   彼此之间可以定义   来电者,通过sepChar,但这是   可选的。默认值为“,”。该   引用字符可以定义   调用者,但这是可选的。该   默认为'“'。如果选项   -alternate是spcified一个稍微不同的语法用于解析   输入。这个语法解释如下,   在格式部分。

答案 1 :(得分:2)

这个问题似乎是一个额外的逗号:你只接受带引号的字符串,如果它们后面有一个逗号。并对非引用的标记执行相同的操作,这有效:

set fresult [regsub -all {(\")([^\"]+)(\")|([^,\"]+)} $line {{\2\4} } fields]
                                        ^(no commas)^

工作示例: http://ideone.com/O2hss

你可以放心地将逗号保留在模式之外 - 正则表达式引擎会热衷于搜索新匹配:它将跳过一个它无法匹配的逗号,并从下一个字符开始。

奖励:这也将使用\"处理转义引号(如果您需要,您应该能够使用""代替\\.轻松适应):

set fresult [regsub -all {"((?:[^"\\]|\\.)+)"|([^,"]+)} $line {{\1\2} } fields]

示例: http://ideone.com/ztkBh

答案 2 :(得分:0)

正如你对@Kobi所说,如果你允许空字段,你应该允许空字符串“” {((\")([^\"]*)(\")|([^,\"]*))(,|$)}其中感兴趣的字段转移到3和5

扩展:{ ( (\")([^\"]*)(\") | ([^,\"]*) ) (,|$) }我承认,我不知道tcl是否允许(?:)非捕获分组。

答案 3 :(得分:0)

使用以下regsub

% set line {12,"34","56,78"}

% regsub -all {(,")|(",)|"} $line " " line

% set line

12 34  56,78  <<< Result

此处所有出现的,"","(按顺序)都会被空格取代

相关问题