Java 正则表达式匹配CSV文件嵌套引号
我知道这已经被讨论过一百万次了。我试着在论坛中搜索,看到了一些很接近的正则表达式,并试图修改它们,但没有效果 假设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做这件事。你想要的是这样的东西。相信我,你不想
“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)