問題來自這個帖子。我沒理解錯的話,樓主的要求是替換分隔符。
這裏假設 csv
的規範是逗號分隔字段,允許字段中有雙引號引用的字符串,如果串內要表示雙引號,那麼用兩個雙引號代替。
例如:
sdf,sdaf"asd""""""asd","asd"
對應的輸出是:
sdf<$>sdafasd"""asd<$>asd
這個問題,似乎一行 Perl 就能解決:
perl -pe 'BEGIN{$sep=q{<$>}}$s="";/(?:([^",]+)(?{$s.=$1})|"(?:([^"])(?{$s.=$2})|""(?{$s.=q{"}}))*"|,(?{$s.=$sep}))+/;$_=$s;'
輸入分成三類:
非雙引號非逗號即 [^",]+,這類直接輸出,這裏用了 Perl 正則內嵌代碼的功能,(?{$s.=$1}) 即把 $1 追加到 $s。 這一部分對應到正則表達式中的
(?:([^",]+)(?{$s.=$1})由一對
non-capturing parentheses即(?:)包起來,裏面先是模式,然後跟着的是Perl正則表達式內嵌代碼即(?{}),用來把匹配的串追加到$2末尾。逗號,這類輸出分隔符 對應
,(?{$s.=$sep})雙引號內的文本,碰到開雙引號後,碰到非雙引號字符則直接輸出,否則用兩個雙引號轉義,碰到單個雙引號則結束。這類用
"(([^"])|"")*"表示。 對應"(?:([^"])(?{$s.=$2})|""(?{$s.=q{"}}))*"`