You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含内嵌引号的CSV字符串分割问题:Java正则表达式失效求助

Hey there! Dealing with tricky CSV data that has embedded or escaped quotes can be such a headache—especially when your go-to regex split suddenly stops working. Let's break down what's going wrong and fix it.

Why Your Original Regex Fails

Your initial regex ,(?=([^\"]*\"[^\"]*\")*[^\"]*$) works for basic quoted CSV fields because it relies on matching commas that sit outside paired double quotes. But when you have a field like "33,"44,55", the unescaped single quote inside breaks the pairing logic. The regex can't distinguish between a quote that's part of the field content and one that closes the field, so it splits incorrectly.

Better Solutions (No More Regex Headaches!)

Regex is great for many tasks, but CSV parsing has edge cases (escaped quotes, newlines in fields, etc.) that make regex unreliable. Here are two solid approaches:

Libraries like Apache Commons CSV handle all CSV edge cases out of the box. They're built specifically for this kind of problem!

Step 1: Add the Dependency

If you're using Maven, add this to your pom.xml:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.10.0</version>
</dependency>

Step 2: Parse Your CSV

This code will correctly handle fields with embedded quotes and commas:

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.StringReader;
import java.io.IOException;

public class CsvHandler {
    public static void main(String[] args) throws IOException {
        // Your input string (note: standard CSV uses "" to escape a single ")
        String input = "111,222,\"33,\"\"44,55\"\",666,\"77,88\",\"99\"";
        
        // Configure CSV format to recognize " as the quote character and "" as escaped "
        CSVFormat csvFormat = CSVFormat.DEFAULT
                .withQuote('"')
                .withEscape('"');
        
        // Parse and iterate through records/fields
        try (CSVParser parser = CSVParser.parse(new StringReader(input), csvFormat)) {
            for (CSVRecord record : parser) {
                for (String field : record) {
                    System.out.println(field);
                }
            }
        }
    }
}

Output:

111
222
33,"44,55
666
77,88
99

2. Manual Parsing with Regex (If You Can't Use Libraries)

If you need to avoid third-party libraries, use a regex that matches entire CSV fields instead of splitting on commas. This handles embedded quotes and commas properly:

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ManualCsvParser {
    public static void main(String[] args) {
        String input = "111,222,\"33,\"44,55\",666,\"77,88\",\"99\"";
        List<String> fields = new ArrayList<>();
        
        // Regex to match: quoted fields (with possible escaped "") or unquoted fields
        Pattern fieldPattern = Pattern.compile("\"([^\"]*(?:\"\"[^\"]*)*)\"|([^,]+)");
        Matcher matcher = fieldPattern.matcher(input);
        
        while (matcher.find()) {
            String field;
            if (matcher.group(1) != null) {
                // For quoted fields, replace "" with " to fix escaped quotes
                field = matcher.group(1).replace("\"\"", "\"");
            } else {
                // Unquoted field, take as-is
                field = matcher.group(2);
            }
            fields.add(field);
        }
        
        // Print the result
        fields.forEach(System.out::println);
    }
}
Key Takeaway

Regex works for simple CSV, but once you hit edge cases like embedded quotes, dedicated CSV libraries are way more reliable. They handle all the weird nuances of the CSV spec so you don't have to!

内容的提问来源于stack exchange,提问作者Shalaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:05:52