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

如何解析含带引号字符串的CSV——进阶场景

解决带引号字符串和引号内分隔符的CSV解析需求

这个问题确实有点棘手,因为Python标准库的csv模块是按照RFC 4180规范设计的——默认会把引号当作字段的边界标记,解析后自动剥离引号,而引号内的分隔符虽然会被当作字段内容,但引号本身留不下来。不过要满足你保留引号+引号内未转义分隔符作为普通字符的需求,完全是可行的,下面给你两种实用方案:

方案一:自定义正则解析(简单直接)

如果你的CSV格式没有太复杂的转义场景(比如字段内没有转义的引号\"),用正则表达式直接匹配字段是最省心的方式。核心思路是:匹配两种字段类型——带引号的完整字段(包括引号本身)、不带引号的普通字段,这样既能保留引号,又不会拆分引号内的分隔符。

示例代码:

import re

def parse_custom_csv(line, delimiter=','):
    # 正则规则:匹配带引号的字段(含引号) 或 不带引号的字段(直到遇到分隔符)
    pattern = re.compile(rf'(?:"[^"]*"|[^{delimiter}]+)')
    # 去除每个字段首尾可能的空白(如果不需要可以去掉这步)
    return [field.strip() for field in pattern.findall(line)]

# 测试用例
test_line = '"user_id","alice, smith",email,"alice@example.com, work"'
result = parse_custom_csv(test_line)
print(result)
# 输出:['"user_id"', '"alice, smith"', 'email', '"alice@example.com, work"']

如果需要支持字段内的转义引号(比如"he said \"hello\""),只需要调整正则规则,让它能识别转义的引号:

def parse_custom_csv_with_escape(line, delimiter=','):
    # 匹配带转义引号的字段:允许字段内出现 \"
    pattern = re.compile(rf'(?:"(?:\\.|[^"])*"|[^{delimiter}]+)')
    return [field.strip() for field in pattern.findall(line)]

# 测试转义引号场景
test_line = '"message","he said \"hello, world\"",status,success'
result = parse_custom_csv_with_escape(test_line)
print(result)
# 输出:['"message"', '"he said \"hello, world\""', 'status', 'success']

方案二:基于标准csv模块改造(兼容复杂场景)

如果你依赖csv模块的其他特性(比如处理多行字段),可以先让csv模块正常解析,再给原本带引号的字段重新添加引号。不过这种方法需要额外判断字段原本是否带引号,这里提供一种思路:

import csv
from io import StringIO

def parse_csv_with_quote_preservation(line, delimiter=','):
    # 先让csv模块解析(此时会剥离引号)
    reader = csv.reader(StringIO(line), delimiter=delimiter)
    parsed_fields = next(reader)
    
    # 重新匹配原行的带引号字段,给对应位置的字段加回引号
    original_fields = re.findall(rf'(?:"[^"]*"|[^{delimiter}]+)', line)
    preserved_fields = []
    for orig, parsed in zip(original_fields, parsed_fields):
        # 如果原字段是带引号的,就保留原引号内容;否则用解析后的内容
        preserved_fields.append(orig if orig.startswith('"') and orig.endswith('"') else parsed)
    return preserved_fields

# 测试
test_line = '"product","laptop, 15-inch",price,"999.99"'
result = parse_csv_with_quote_preservation(test_line)
print(result)
# 输出:['"product"', '"laptop, 15-inch"', 'price', '"999.99"']

总结

  • 如果你不需要处理多行字段、转义引号之外的复杂场景,方案一的正则解析是最直接高效的选择,完全满足你的两个核心需求。
  • 如果需要兼容csv模块的高级特性,再考虑方案二的改造方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:23:49