正则表达式匹配双引号可选的值

时间:2015-01-08 02:06:21

标签: regex regex-lookarounds

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

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

示例输入

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

最终输出

匹配信息是
第一行匹配

\1 1a
\2 2a 2.1a 2.2a
\3 3a

第二行匹配

\1 4b
\2 5.5b 5.6b 5.7b
\3 6b

第3行匹配

\1 7c
\2 8c
\3 9c

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

我尝试使用正则表达式:

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

链接:

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

2 个答案:

答案 0 :(得分:5)

您可以在模式中简单地引用optional。通过使用?跟随前面的标记,您告诉正则表达式引擎匹配前面的“零和一”时间。

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

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

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

答案 1 :(得分:3)

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

您可以使用以下方法解析此问题:

([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]+)

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

  • \1 -> \1
  • \2 -> \3 (with quotes) or \4 (without quotes)
  • \3 -> \5

也可以使用\2代替旧版\2,但新\2也会包含引号",如果它们是字符串的一部分。

因此,正确处理它们会花费更多的后期处理。