Java 正则表达式匹配CSV文件嵌套引号

Java 正则表达式匹配CSV文件嵌套引号,java,regex,csv,Java,Regex,Csv,我知道这已经被讨论过一百万次了。我试着在论坛中搜索,看到了一些很接近的正则表达式,并试图修改它们,但没有效果 假设CSV文件中有一行,如下所示: “123”,456,“701”B街,910 ^^^ 是否有一个简单的正则表达式来检测“B”(因为它是正常CSV引号中的一组非转义引号)并用类似“B\”的东西替换它?最后一个字符串的结果如下所示: “123”,456,“701\'B\'Street”,910 非常感谢您的帮助 相信我,你不想用regex做这件事。你想要的是这样的东西。相信我,你不想

我知道这已经被讨论过一百万次了。我试着在论坛中搜索,看到了一些很接近的正则表达式,并试图修改它们,但没有效果

假设CSV文件中有一行,如下所示:

“123”,456,“701”B街,910
^^^
是否有一个简单的正则表达式来检测
“B”
(因为它是正常CSV引号中的一组非转义引号)并用类似
“B\”的东西替换它?最后一个字符串的结果如下所示:

“123”,456,“701\'B\'Street”,910

非常感谢您的帮助

相信我,你不想用regex做这件事。你想要的是这样的东西。

相信我,你不想用regex做这件事。您需要这样的库。

有无数个库可以帮助您解析CSV,但是如果您出于学术原因想要使用regexp,这可能会有所帮助:

  • 带转义支持的带引号的字符串。 “(\\.\[^\\”])*”
  • 无引号字段:[^”,]*
  • 分隔符:*
我不使用CSV文件,因此我不确定“其他CSV字段”的有效性(例如上面匹配的456),或者/、*/是否是您想要的分隔符

无论如何,组合上述内容将匹配一个字段和一个分隔符(或字符串结尾):


有无数个库可以帮助您解析CSV,但如果出于学术原因想使用regexp,这可能会有所帮助:

  • 带转义支持的带引号的字符串。 “(\\.\[^\\”])*”
  • 无引号字段:[^”,]*
  • 分隔符:*
我不使用CSV文件,因此我不确定“其他CSV字段”的有效性(例如上面匹配的456),或者/、*/是否是您想要的分隔符

无论如何,组合上述内容将匹配一个字段和一个分隔符(或字符串结尾):


我会使用定制的sed表达式作为

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

我会使用定制的sed表达式作为

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

您的示例不正确:

“123”,456,“701”B街,910
这实际上应该是:

“123”,456,“701”B“街”,910
(当然,CSV有很多变体,但由于大多数时候人们希望它与excel或access一起使用,所以我坚持使用Microsoft的定义。)

因此,用于此的正则表达式可以如下所示:

“+()。+()。+”
组(在括号中)将是双引号,其余的将确保它们位于另一组引号中


这涵盖了你需要的查找部分。替换零件取决于您正在使用的编程内容。

您的示例不正确:
(?<!^)(?<!",)(?<!\d,)"(?!,")(?!,\d)(?!$)(?!,-\d)

“123”,456,“701”B街,910
这实际上应该是:

“123”,456,“701”B“街”,910
(当然,CSV有很多变体,但由于大多数时候人们希望它与excel或access一起使用,所以我坚持使用Microsoft的定义。)

因此,用于此的正则表达式可以如下所示:

“+()。+()。+”
组(在括号中)将是双引号,其余的将确保它们位于另一组引号中



这涵盖了你需要的查找部分。更换部件取决于您正在使用的编程方式。

(?
(?456和910应该被引用吗?或者你只引用了CSV中的一些字段吗?可能引用了一些字段的副本,而有些字段不是不幸的。这样的事情似乎很接近,但不完全是我想要的:456和910应该被引用吗?或者你只引用了CSV中的一些字段吗?可能是d有些字段是重复引用的,有些并不是不幸的。像这样的事情似乎很接近,但不完全是我想要的:是的,我同意。不幸的是,我是一个使用基于StreamTokenizer的解决方案的低级开发人员,不幸的是,我不能放弃它。但是,如果这些内部引用被转义,它会工作得很好。@user361970-如果你有你需要修复一个坏的解决方案,当然你可以放弃它,把它做得更好。当然,我们这里谈论的代码不能超过100行。如果你的老板不这么说,请把他发送给我们,这样我们就可以向他解释为什么修补坏代码是个坏主意。我同意StreamTokenizer甚至令人担忧。不幸的是,我是一个低级别的开发人员使用基于StreamTokenizer的解决方案,不幸的是,我不能放弃它。但是,如果这些内部引号被转义,它会很好地工作。@user361970-如果您有一个损坏的解决方案需要修复,当然您可以放弃它并做得更好。当然,我们这里谈论的代码不能超过100行。如果您的老板不这样说,将他发送到,以便我们可以向他解释为什么修补坏代码是一个坏主意。StreamTokenizer甚至是一个坏主意。这可能是一种解决方法。我如何修改此方法以使用\进行转义,而不是替换为空字符串?简单的
's/\(.*),\(.*),\(.\)“\(.*\”,(.*)/\1、\2、\3\\\\“\4\\”\5\6/g'
注意\\将导致打印\和“将打印”大约\4希望能回答这个问题。我想我需要上一些sed课程。我在cygwin sed中得到这个测试:-e expression#1,char 58:`s'命令的rhs格式上的无效引用\6把sed表达式上面的内容搞乱了。看看我的原始答案,保持正则表达式部分不变..只需将\4更改为\ \“\4\”这可能是中间的方法。我如何修改它以转义为\而不是替换为空字符串?简单的
's/\(.*\)、\(.*\)、\(.*\)“\(.*\)”、\(.*\)/\1、\2、\3\\\\”\4\\\“\5\6/g'
注意\\将导致打印\和“将打印a”大约\4希望能回答这个问题。我想我需要上一些sed课程。我在cygwin sed中得到这个测试:-e expression#1,char 58:`s'命令的rhs格式上的无效引用\6把sed表达式上面的内容搞乱了。看看我的原始答案,保持正则表达式部分不变..只需将\4改为\\\\\\\\\\\\\ 4\\\\\\\不完全正确。在
(?<!^)(?<!",)(?<!\d,)"(?!,")(?!,\d)(?!$)(?!,-\d)