【问题标题】:regex to extract all that in quotes正则表达式提取引号中的所有内容
【发布时间】:2013-12-26 11:42:14
【问题描述】:

我正在尝试编写一个正则表达式来匹配出现在封闭字符之间的所有字符串(很可能是" - 双引号)。这是我在尝试解析 csv 文件中的一行时经常遇到的场景。

所以我有一个示例行,例如:

"Smith, John",25,"21/45, North Avenue",IBM

尝试了以下正则表达式:

"(.*)"

但它的获取方式如下:

我期望输出如下:

Smith, John
25
21/45, North Avenue
IBM

我编写的正则表达式试图在我的示例中捕获" 之间的内容。但是,以上是我期望的输出。

虽然有一种模棱两可的地方:我不是在寻找像:,25, 这样的匹配项。这有点让我想知道正则表达式在这里是否可行。

正确的写法是什么?

【问题讨论】:

  • "([^"]*)""(.*?)" 会起作用,但会产生另一个问题。
  • 您将使用哪种语言的正则表达式?
  • @SalmanA 你能解释一下有问题的场景吗...
  • @deostroll:我看到两个问题:1)您必须处理捕获组,2)您必须处理转义引号。
  • 我宁愿使用一个好的 CSV 解析器库而不是使用 RegEx。问题是John Smith,25,"21/45, North Avenue",IBM"John ""Microsoft Guy"" Smith",25,"21/45, North Avenue",IBM 都是 CSV 数据的有效示例。

标签: regex parsing csv


【解决方案1】:

首先,这只会捕获一个组。其次,你需要不贪心:

(?:"(.*?)")

这并不能解决您在一行中有多个匹配项的问题。 这里有两个例子:

import re
string = '"Smith, John",25,"21/45, North Avenue",IBM'
pattern = r'(?:"(.*?)")'
re.findall(pattern, string)
> ['Smith, John', '21/45, North Avenue']

在 C# 中:

string pattern = @"(?:\""(.*?)\"")";
string input = @"\""Smith, John\"",25,\""21/45, North Avenue\"",IBM'";
foreach (Match m in Regex.Matches(input, pattern)) 
    Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);

【讨论】:

    【解决方案2】:

    如果您真的想推出自己的 CSV 解析器,则需要教您的正则表达式一些规则:

    1. 字段可以不加引号,只要它不包含引号、逗号或换行符。
    2. 带引号的字段可以包含任何字符;引号通过加倍转义。
    3. 逗号用作分隔符。

    因此,要匹配一个 CSV 字段,您可以使用以下正则表达式:

    (?mx)       # Verbose, multiline mode
    (?<=^|,)    # Assert there is a comma or start of line before the current position.
    (?:         # Start non-capturing group:
     "          # Either match an opening quote, followed by
     (?:        # a non-capturing group:
      ""        #  Either an escaped quote
     |          #  or
      [^"]+     #  any characters except quotes
     )*         # End of inner non-capturing group, repeat as needed.
     "          # Match a closing quote.
    |           # OR
     [^,"\r\n]+ # Match any number of characters except commas, quotes or newlines
    )           # End of outer non-capturing group
    (?=,|$)     # Assert there is a comma or end-of-line after the current position
    

    live on regex101.com

    【讨论】:

    • 你确定引号会用 .net 样式转义吗?
    • @CasimiretHippolyte 我不会太担心目标语言以及某些必需字符是如何转义的。也许甚至引用字符可能会有所不同......即它可能不是";它可能是',或者任何标点符号......底线不是我担心的......
    • @CasimiretHippolyte:嗯,至少 CSV 编码器通常会这样做。请参阅en.wikipedia.org/wiki/… - 但我不排除其他方法。
    • @TimPietzcker:确实!我不知道。
    【解决方案3】:

    请不要为此使用正则表达式,CSV 应由解析器处理。

    这是一个现成的解析器: http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader

    您还可以使用 OLEDB 内置解析器: http://www.switchonthecode.com/tutorials/csharp-tutorial-using-the-built-in-oledb-csv-parser

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 2023-04-05
      • 2011-07-23
      • 1970-01-01
      • 2017-12-29
      • 2020-09-27
      相关资源
      最近更新 更多