首页 文章

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

提问于
浏览
2

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

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

Sample Input

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

Final output

匹配信息是
1st row match

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

2nd row match

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

3rd row match

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

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

Regex i tried:

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

Link:

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

2 回答

  • 5

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

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

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

    ? 表示组(或本例中的字符 " )是可选的 .

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

    EDIT

    @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 将包括引号 " .

    因此,它将花费更多的后处理来正确处理它们 .

  • 3

    您可以在模式中简单地引用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]+)
    

相关问题