2010-06-09 60 views
0

我知道这已经被讨论了一百万次。我试图通过论坛搜索,并看到一些密切的正则表达式,并试图修改它们,但无济于事。正则表达式匹配CSV文件嵌套引号

说有是一个CSV行文件中像这样:

"123", 456, "701 "B" Street", 910 
       ^^^ 

有一个简单的正则表达式来检测"B"(因为它是一个非转义设定的正常CSV引号中引号)并更换它有像\"B\"?最后的字符串最终会看起来像这样:

"123", 456, "701 \"B\" Street", 910 

帮助将不胜感激!

+0

456和910应该被引用?或者,您是否只在CSV中引用了一些字段? – 2010-06-09 02:07:08

+0

[在java中使用RegEx解析CSV输入](http://stackoverflow.com/questions/1441556/parsing-csv-input-with-a-regex-in-java) – 2010-06-09 02:07:52

+0

有些字段被引用,有些字段不幸的是 – user361970 2010-06-09 02:09:55

回答

4

相信我你不想用正则表达式来做到这一点。你想要类似Java CSV Library

+0

是的,我同意。不幸的是,我是一位低劣的开发人员,使用基于StreamTokenizer的解决方案,但不幸的是我们无法完全放弃。如果那些内部引号被转义了,它会工作得很好。 – user361970 2010-06-09 02:26:45

+1

@ user361970 - 如果您有一个需要修复的解决方案,*当然*您可以放弃它并做得更好。当然,我们不能在这里谈论超过100行的代码。如果您的老板不这么说,请将他发送给SO,以便我们向他解释为什么修补错误代码是个坏主意。 – 2010-06-09 04:16:06

+0

StreamTokenizer甚至是WORSE – 2010-06-09 13:12:12

1

有几个数不胜数库,帮助你解析CSV,但如果你想使用学术原因正则表达式,这可能会帮助:

  • 引号字符串与逃生支持。 “(\\ | [^ \\”])* “
  • 不带引号的字段:[^”] *
  • 分隔符:*

我不使用CSV文件,因此,我不确定'其他csv字段'的有效性(匹配456,例如上面),或者/,* /是否是您想要的分隔符。

无论如何,将上面的结果匹配一个字段和一个定界符(或字符串的末尾):

(quotedstring|unquoted)(delimiter|$) 
0

我会用一个定制SED表达

's/\(.*\),\(.*\),\(.*\)"\(.*\)\" \(.*\),\(.*\)/\1,\2,\3 \4 \5 \6/g' 
+0

这可能是在interm – user361970 2010-06-09 03:11:34

+0

的方式我将如何修改此转义\而不是替换为空字符串? – user361970 2010-06-09 03:27:24

+0

简单 's/\(。* \),\(。* \),\(。* \)“\(。* \)\”\(。* \),\(。* \)/ \ 1,\ 2,\ 3 \\\“\ 4 \\”\ 5 \ 6/g'' 请注意\\将导致打印\和“将打印一个”,希望能够回答它。 – 2010-06-09 03:57:23

0

你举的例子是不妥当的CSV:

"123", 456, "701 "B" Street", 910 

这实际上应该是:

"123", 456, "701 ""B"" Street", 910 

(有很多变化CSV,当然,但由于大多数时间人们都希望它与Excel或Access一起使用,所以我坚持微软的定义。)

因此此正则表达式可以看起来像:

".+("").+("").+" 

在组(括号内)将是你的双引号,其余的保证,他们正在另一组引号内找到。

这涵盖了您的需求的一部分。替换部分取决于你在编程。

+0

不完全。在CSV情况下,你正在寻找一个像'([^“] |”“)*':匹配由非引号或两个引号构成的标记的模式,'。+'无论如何都可以匹配单引号和'。 +(“”)。+(“”)。+'假定格式太特殊 - 它只允许两个引号,而'+'需要在它们之前,之间和之后的字符 – Kobi 2010-06-09 04:32:23

+0

Ahh ...对吧。晚饭后我得到了如此接近的答案,总是让我的困惑和星号混淆...... – Ricosuave 2010-06-09 06:20:35

0
(?<!^)(?<!",)(?<!\d,)"(?!,")(?!,\d)(?!$)(?!,-\d) 

我得到这个工作,我还以为会后,如果其他人正在寻找一个答案