正则表达式以匹配可选的双引号括起来的值

Regex to match the value optionally enclosed by double quotes

我有 3 列由空格分隔,但第二个字段可选择用双引号引起来。

我想提取第一个字段、第二个字段(双引号内的值)和第三个字段,有时第二个字段的值可能没有包含在双引号内,在这种情况下只是 return 现有的值。

示例输入

1a "2a 2.1a 2.2a" 3a
4b "5.5b 5.6b 5.7b" 6b
7c 8c 9c

最终输出

匹配信息是
第 1 行匹配

 1a
 2a 2.1a 2.2a
 3a

第二行匹配

 4b
 5.5b 5.6b 5.7b
 6b

第 3 行匹配

 7c
 8c
 9c

我尝试了下面的正则表达式,前两个输入工作正常,但第三行不匹配,有人可以帮我解决这个问题吗?

我试过的正则表达式:

([a-z0-9]+)\s+"([a-z0-9\s.]+)"\s+([a-z0-9]+)

链接:

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

您的正则表达式的问题在于,是否引用值是可选的。

您可以使用以下方法解析:

([a-z0-9]+)\s+"?([a-z0-9\s.]+)"?\s+([a-z0-9]+)

? 表示组(或字符 " 在这种情况下)是可选的。

这让我想知道你想做什么?这看起来很像 bash 参数解析。有时您可以利用图书馆...

编辑

@PetSerAl 提出了一个有效的观点:两个引号 " 是相互独立的,所以:

4b "5.5b 5.6b 5.7b 6b
4b 5.5b 5.6b 5.7b" 6b

也会匹配,你可以通过引入额外的捕获组来解决这个问题:

([a-z0-9]+)\s+("([a-z0-9\s.]+)"|([a-z0-9\s.]+))\s+([a-z0-9]+)

在这种情况下,旧捕获组映射到新捕获组如下:

  • ->
  • -> (with quotes) or (without quotes)
  • ->

也可以将 </code> 用于旧的 <code>,但新的 </code> 也将包含引号 <code>"(如果它们是字符串的一部分)。

因此正确处理它们将花费更多的后处理。

您可以简单地在您的模式中使用引号 optional。通过在前面的标记后面加上 ?,您告诉正则表达式引擎在 "zero and one" 时间之间匹配前面的标记。

([a-z0-9]+)\s+"?([a-z0-9\s.]+)"?\s+([a-z0-9]+)

如果您的语言支持,您可以使用分支重置功能。通过使用此功能,备选方案中的两个捕获组都被视为一个捕获组。

([a-z0-9]+)\s+(?|"([^"]+)"|([a-z0-9]+))\s+([a-z0-9]+)