假设 csv 代码片段格式错误,使用分号作为字段终止符:
abc;d" "e"f;"ijk"
根据RFC4180字段内的 dquote 应由两个 dquote 表示:
abc;d"" ""e""f;"ijk"
我试图通过一个sed
脚本来实现这一点,该脚本匹配任何不在字段终止符前面或后面的 dquote(此处;
):
echo 'abc;d" "e"f;"ijk"' | sed -e 's/\([^;]\)"\([^;]\)/\1""\2/g'
结果几乎是好的:
abc;d"" "e""f;"ijk"
除了之前的双引号e
不匹配因此不重复。
有人能解释一下为什么这不起作用吗,因为前后e
没有分号。
答案1
您的第二条引号不匹配,因为匹配项是space quote e
,并且space
已被前面的所消耗d quote space
。
这是一个教科书式的例子环视匹配,匹配但不消耗。不幸的是,在中未实现环视匹配。sed
如果我必须使用sed
,我会先用一些不出现的字符替换有效引号,然后将所有剩余的引号加倍,然后放回有效引号。
Perl 具有环视匹配功能,这对眼睛来说(稍微)更容易理解一些:
$ echo 'abc;d" "e"f;"ijk"' | perl -pe 's/(?<!;)"(?![;\n])/""/'g
abc;d"" ""e""f;"ijk"
翻译:引号前面没有正则表达式;
,后面也没有正则表达式[;\n]
。
之所以有 \n,是因为 perl 认为它是行的一部分,因此会匹配最后一个引号,除非我们禁止它。