【问题标题】:Match CSV line with semicolons and quotation inside a quoted string在带引号的字符串中使用分号和引号匹配 CSV 行
【发布时间】:2017-07-31 10:20:50
【问题描述】:

我正在尝试解析单个 csv 文件。 目前它是通过一些在线正则表达式网页完成的,但最终它必须在 c# 中实现。 (作为对 cme​​ts 中某些问题的反应)

我在这里阅读了很多关于 SO 的其他文章,以便自己弄清楚, 但我一直在解决它。

我的 RegExp 测试行如下所示(更新:引号在带引号的字符串中转义):

;;"test123;weiterer Text";;"Test mit " Zeichen im Spaltenwert";nächste Spalte mit " Begrenzungszeichen;"4711";irgendwas 123,4;1222;"foo"test"

;;"test123;weiterer Text";;"Test mit "" Zeichen im Spaltenwert";nächste Spalte mit "" Begrenzungszeichen;"4711";irgendwas 123,4;1222;"foo""test"
  • ; 是分隔符
  • " 是引用列的符号

问题:

  • 该行可能包含空列(分号后跟分号 没有任何文字)
  • 带引号的字符串可能包含引号,就像这里 "Test mit " Zeichen im Spaltenwert"
  • 列分隔符也可能出现在带引号的字符串中,例如:“test123;weiterer Text”

到目前为止,我通过几次谷歌搜索所做的事情以及我对正则表达式的有限理解就是这个表达式

(?

这给出了以下结果

        [0] => 
        [1] => 
        [2] => "test123
        [3] => weiterer Text"
        [4] => 
        [5] => "Test mit " Zeichen im Spaltenwert"
        [6] => nächste Spalte mit " Begrenzungszeichen
        [7] => "4711"
        [8] => irgendwas 123,4
        [9] => 1222
        [10] => "foo"test"

经过测试 https://www.myregextester.com/

我现在遇到的问题是元素 2 和 3。这个文本

"test123;weiterer Text"

必须是一列,但在引号字符串内的分号处被拆分,尽管我认为我告诉表达式匹配引号内的所有内容。

非常感谢这里的任何帮助。 提前致谢。

【问题讨论】:

  • “你的正则表达式风格是什么”是什么意思?我不明白。使用 csv 解析器可能是未来的一个选项,但目前不是因为我必须解决这个问题的现有实现。
  • 当前使用提到的 url 下的工具,myregextester.com 但最后使用 C#
  • 如果引用部分还可以包含未转义的引用,则无法解决您的问题。
  • @CasimiretHippolyte 好的,这是一个很好的提示。那是我的测试数据的错。到目前为止。但是如果引用字符串中的引号被转义了,那怎么解决呢?
  • 这是一个有效的 CSV 字符串输入吗?如果是,不要使用正则表达式,使用内置的 CSV 解析器。

标签: c# regex csv double-quotes


【解决方案1】:

假设一个正确的 csv 使用双引号进行转义 (""),您可以使用逐行读取

"(?:[^"]+|"")*"|[^;]+|(?<=;|^)(?=;|$)

基本上三种不同的方式来匹配一列:

  • "(?:[^"]+|"")*" 开始和结束引号之间有非引号或双引号
  • [^;]+ 一系列非分号
  • (?&lt;=;|^)(?=;|$) 分号之间或分号和开始/结束之间的空白字段

注意:

  • 如果您想在多行上下文中使用它,您必须在否定字符类中添加 \n
  • 它不处理与引用字段连接的前导或尾随空格

https://regex101.com/r/twKZVN/1

(虽然 regex 101 测试 PCRE 模式,但使用的所有功能也可用于 .net 模式。

【讨论】:

    【解决方案2】:
    (?<=^|;)(\"[^"]*\";|\".\"|[^;]*)|[^;]+
    

    添加此部分用于合并 2 和 3 \"[^"]*\";

    [0] => Array
        (
            [0] => 
            [1] => 
            [2] => "test123;weiterer Text";
            [3] => 
            [4] => "Test mit " Zeichen im Spaltenwert"
            [5] => nächste Spalte mit " Begrenzungszeichen
            [6] => "4711";
            [7] => irgendwas 123,4
            [8] => 1222
            [9] => "foo"test"
        )
    

    【讨论】:

    • 您可能知道如何匹配这样的列?目前不是。 "foo"te;st"(同一列中的引号和分号)
    猜你喜欢
    • 1970-01-01
    • 2011-04-16
    • 2016-06-08
    • 1970-01-01
    • 2015-02-15
    • 2015-09-16
    • 2011-01-30
    • 2023-03-27
    相关资源
    最近更新 更多