sed 中的正则表达式:匹配前面或后面没有特定其他字符的字符

sed 中的正则表达式:匹配前面或后面没有特定其他字符的字符

假设 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 认为它是行的一部分,因此会匹配最后一个引号,除非我们禁止它。

相关内容