猿问

在双引号外的逗号上拆分。如果是单引号,则忽略双引号

我有两种类型的字符串,我需要使用逗号分隔

第一种(1" 表示 1 英寸)

130,TEXT 1" 67 SERIES ,400,4,1,998,.010,9,-,7,130

第二种

130,"TEXT, SAMPLE TEXT",400,4,1,998,.010,9,-,7,130

在第一种类型中,我需要按原样获取字符串并使用拆分,因此我的拆分值将是 130 和 TEXT 1" 67 SERIES 等等。

但是在第二种类型中,我需要忽略双引号之间的逗号并将字符串作为一个整体。

我用这个分开

a.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)")

它通过了第二个案例,但在第一个案例中失败了。请帮忙


阿波罗的战车
浏览 97回答 2
2回答

繁星coding

您的输入格式不是有效的 CSV 格式。根据 Wikipedia Comma-separated values page,如果完全使用引号,则必须引用字段中的文字引号字符。这意味着任何现有的通用 CSV 解析器库都不太可能处理同一文件中的两种类型的行。为了说明这个问题有多深,请考虑:   130,TEXT 1" 67 SERIES, TEXT 2",4,1,998,.010,9,-,7,130这可能意味着:一个字段包含TEXT 1" 67 SERIES, TEXT 2"一个包含TEXT 1 67 SERIES, TEXT 2, 或两个字段TEXT 1" 67 SERIES和TEXT 2"。消除歧义的唯一方法是编写一些自定义逻辑以对其进行分类......基于您自己的业务规则。我不认为你可以用split和正则表达式来做到这一点。您需要编写一个适当的自定义解析器。但在这种情况下,我认为您有权反对创建此 CSV 数据的任何人/任何人。他们应该遵守规则。我很想实现我的系统,通过现成的语法检查器提供 CSV 文件,并自动拒绝任何未通过验证的文件。您可以自动修复报价中的错误吗?我认为不是……在一般情况下。如前所述,无法判断格式错误的 CSV 中的双引号是否应该是文字。它需要人类智能和领域知识来理解数据的含义。

米琪卡哇伊

不知道如何(如果有的话)使用单个正则表达式来完成。但这是一种蛮力方法,它计算字符串中引号的数量并从那里开始。public static void main(String[] args) {&nbsp; &nbsp; System.out.println("---Type 1---");&nbsp; &nbsp; for (String s : split("130,TEXT 1\" 67 SERIES ,400,4,1,998,.010,9,-,7,130")) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(s);&nbsp; &nbsp; }&nbsp; &nbsp; System.out.println("\n---Type 2---");&nbsp; &nbsp; for (String s : split("130,\"TEXT, SAMPLE TEXT\",400,4,1,998,.010,9,-,7,130")) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(s);&nbsp; &nbsp; }}private static List<String> split(String str) {&nbsp; &nbsp; List<String> tokens = new ArrayList<>();&nbsp; &nbsp; if (str.split("\"").length > 2) {&nbsp; &nbsp; &nbsp; &nbsp; int firstQuoteIndex = str.indexOf("\"");&nbsp; &nbsp; &nbsp; &nbsp; int secondQuoteIndex = str.indexOf("\"", firstQuoteIndex + 1);&nbsp; &nbsp; &nbsp; &nbsp; tokens.add(str.substring(0, firstQuoteIndex - 1));&nbsp; &nbsp; &nbsp; &nbsp; tokens.add(str.substring(firstQuoteIndex + 1, secondQuoteIndex));&nbsp; &nbsp; &nbsp; &nbsp; tokens.addAll(Arrays.asList(str.substring(secondQuoteIndex + 2).split(",")));&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; tokens.addAll(Arrays.asList(str.split(",")));&nbsp; &nbsp; }&nbsp; &nbsp; return tokens;}输出---Type 1---130TEXT 1" 67 SERIES&nbsp;40041998.0109-7130---Type 2---130TEXT, SAMPLE TEXT40041998.0109-7130
随时随地看视频慕课网APP

相关分类

Java
我要回答