【问题标题】:Parse CSV file with commas inside fields在字段内使用逗号解析 CSV 文件
【发布时间】:2014-10-22 01:45:42
【问题描述】:

我刚收到同事发来的文件,不知道如何解析:

输入:

key,value1,"value2,hello"

期望的输出:

key,value2

Perl 或 Python 是我理解的语言。

谢谢,伯纳多

【问题讨论】:

  • 到目前为止你有什么尝试?你使用什么工具?看起来awksed 可以很容易地做到这一点,你试过使用它们吗?

标签: python regex perl parsing module


【解决方案1】:

标准 Perl 模块 Text::ParseWords 可用于处理 CSV 文件。

#!/usr/bin/perl

use strict;
use warnings;

use Text::ParseWords;

while (<DATA>) {
  my @fields = parse_line(',', 0, $_);

  # Do something useful with the data in @fields
  print join ' | ', @fields;
}
__DATA__
key,value1,"value2,hello"

【讨论】:

    【解决方案2】:

    这是valid CSV syntax,因此您可以使用 CSV 解析器。

    您没有指定您使用的语言,但大多数都有一个 CSV 解析器在类库中很容易获得(例如,.NET 中的TextFieldParser)或作为外部组件(例如,Apache 中的CSVParser Java 的 Commons)。

    如果你确实想重新发明轮子(我不推荐这样做),算法很简单:

    result = "", inQuotes = false
    read next character
    if end-of-line:
        if inQuotes:
            throw error (unmatched quotes)
        yield result
        return
    else if character = '"':
        invert inQuotes
    else if character = ',' and not inQuotes:
        yield result
        result = ""
    else:
        result += character
    

    【讨论】:

      【解决方案3】:

      使用正则表达式的最佳方法:

      [^,"]+|"(?:[^"]|"")+"
      

      Debuggex Demo

      【讨论】:

      • 根据the CSV standard,反斜杠在CSV中没有特殊含义。引号内的引号将通过重复进行转义。
      • 这不考虑不匹配的引号,如果您有一个空值test,,test2,也不会返回空查找。您可以将其更改为[^,"]*|"(?:[^"]|"")*",但即使存在匹配项,也会为您提供空匹配项(正则表达式特权)。
      • 感谢@Heinzi,已相应更改。
      【解决方案4】:

      如果你想在这个任务中使用正则表达式,以下应该可以工作:

      (\S+,)\d+,\"(\d+),\S+\"
      

      (\S+,) 是第一个捕获组,它选择第一个键,包括逗号。后面是一些数字、逗号和引号\d+,\"。第二个捕获组(\d+)选择第二个值,后跟逗号、字符串和引号:,\D+\"

      但正如其他人已经写的那样,还有其他不涉及正则表达式的解决方案。

      【讨论】:

        【解决方案5】:
        (.*?)\,.*?\"(.*?)\,.*
        

        你可以试试这个。

        查看演示。

        http://regex101.com/r/rI6jZ0/2

        【讨论】:

          猜你喜欢
          • 2011-05-11
          • 1970-01-01
          • 2014-07-02
          • 2011-05-20
          • 2011-10-01
          • 2015-10-24
          • 2020-06-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多