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

假设使用分号作为字段终止符的格式错误的csv代码片段:

abc;d" "e"f;"ijk"

根据RFC4180,字段中的一个dquote应该用两个dquotes来表示:

abc;d"" ""e""f;"ijk"

我试图通过一个sed脚本来实现这个匹配任何没有前或后跟字段终止符(here ; )的dquote:

 echo 'abc;d" "e"f;"ijk"' | sed -e 's/\([^;]\)"\([^;]\)/\1""\2/g' 

结果几乎是好的:

 abc;d"" "e""f;"ijk" 

除非e之前的双引号不匹配,因此不能重复。

任何人都可以解释为什么这是行不通的,因为之前和之后没有分号。

您的第二个报价不匹配,因为匹配是space quote e ,并且space已经被前面的d quote space消耗。

这是查找匹配的教科书示例,匹配但不消耗。 不幸的是,周围的匹配没有在sed实现。 如果我不得不使用sed这个事情,我会先用有些不存在的字符replace有效的引号,然后加倍所有剩下的引号,然后把有效的引号放回去。

Perl有一个lookaround的匹配,这是(稍微)在眼睛上更容易:

 $ echo 'abc;d" "e"f;"ijk"' | perl -pe 's/(?<!;)"(?![;\n])/""/'g abc;d"" ""e""f;"ijk" 

翻译:在正则expression式之前没有引号; ,之后是正则expression式[;\n]

\ n在那里是因为perl认为它是行的一部分,因此将匹配最后的引用,除非我们禁止它。