You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则解析含引号的复杂分隔属性字符串?

问题描述

给定字符串:

def str='prop1: value1, prop2: value2;value3, prop3:"test:1234, test1:23;45, test2:34;34", prop4: "test, 66;77, 888"'

期望解析为以下属性-值对:

prop1: value1
prop2: value2;value3
prop3: test:1234, test1:23;45, test4:34;34
prop4: test, 66;77, 888

尝试用Groovy正则提取带引号的键值对时,仅能匹配prop3,无法匹配prop4,代码如下:

def str='prop1: value1, prop2: value2;value3, prop3:"test:1234, test1:23;45, test4:34;34", prop4: "test, 66;77, 888"'
def regex = /(\w+):"(.*)"[,\s]|$/
def m = (str =~ regex)
(0..<m.count).each{
    println("${m[it][1]}=${m[it][2]}")
}

运行结果:

prop3=test:1234, test1:23;45, test2:34;34
null=null
问题分析与解决

1. 无法匹配prop4的原因

你的正则存在两个核心问题:

  • 未处理冒号与引号间的空格:prop4的格式是prop4: "...",而正则(\w+):"要求冒号后直接跟引号,忽略了中间的空格,导致匹配失败。
  • 正则逻辑冗余:末尾的[,\s]|$写法混乱,且(.*)贪婪匹配可能引发意外匹配,但核心问题是空格未兼容。

修正后的带引号键值匹配正则及代码:

def str='prop1: value1, prop2: value2;value3, prop3:"test:1234, test1:23;45, test4:34;34", prop4: "test, 66;77, 888"'
def regex = /(\w+):\s*"(.*?)"(?:,|$)/
def m = (str =~ regex)
(0..<m.count).each{
    println("${m[it][1]}=${m[it][2]}")
}

运行结果:

prop3=test:1234, test1:23;45, test4:34;34
prop4=test, 66;77, 888

2. 一次正则扫描完成全量解析

可以通过分支正则同时匹配带引号和不带引号的键值对,无需拆分两次。正则逻辑:

  • (\w+):匹配属性名
  • :\s*:匹配冒号及后续可选空格
  • (?:"(.*?)"|([^,]+)):分支匹配值——要么是带引号的非贪婪匹配内容,要么是到下一个逗号前的所有字符
  • (?:,|$):匹配结尾的逗号或字符串结束(非捕获组,避免冗余捕获)

实现代码:

def str='prop1: value1, prop2: value2;value3, prop3:"test:1234, test1:23;45, test4:34;34", prop4: "test, 66;77, 888"'
def regex = /(\w+):\s*(?:"(.*?)"|([^,]+))(?:,|$)/
def m = (str =~ regex)
(0..<m.count).each { idx ->
    def key = m[idx][1]
    // 合并两个捕获组的结果,两种匹配场景只会有一个有值
    def value = m[idx][2] ?: m[idx][3].trim()
    println("${key}: ${value}")
}

运行结果完全符合期望:

prop1: value1
prop2: value2;value3
prop3: test:1234, test1:23;45, test4:34;34
prop4: test, 66;77, 888

内容的提问来源于stack exchange,提问作者mike01010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:54:59