含转义分号的键值对字符串解析求助:正则/算法优化
解析带转义分号的键值对字符串方案
问题背景
我们需要解析一种键值对格式的字符串:
- 键值对之间用
;分隔,格式示例:Key=Value;key1=value1; - 值中的
\;是转义表示,实际对应普通分号;,不能作为键值对的分隔符
当前遇到的问题:输入Key=Value\;key1=value1\;key2=value2\;key3=value3;时,现有正则仅解析出1个键值对,期望得到4个独立的键值对(Key、key1、key2、key3分别对应各自的值)。
约束条件
- 值可以是任意字符串,包括包含其他键、等号的内容
- 键可以是任意字符串
- 键值对数量不限
- 值允许为空
- 已知键列表,但用户可能不填写全部键
解决方案
方案1:优化正则表达式
核心思路是匹配未被转义的分号作为键值对的分隔符,同时正确区分键(到第一个未被转义的等号)和值(到下一个未被转义的分号或字符串结尾)。
正则表达式
([^=]+)=(.*?)(?=(?<!\\);|$)
说明
([^=]+):匹配键的部分,直到第一个未被转义的=(因为键和值用=分隔,值里可以有=,所以键取到第一个=为止)(.*?):非贪婪匹配值的内容,避免过度匹配(?=(?<!\\);|$):正向预查,确保值的结尾是未被转义的分号或者字符串结束位置((?<!\\)是负向预查,匹配前面没有反斜杠的;)
使用步骤
- 启用全局匹配模式(如Java的
Pattern.CASE_INSENSITIVE | Pattern.DOTALL,JavaScript的/g)匹配目标字符串 - 对每个匹配结果,将第1组作为键,第2组作为值
- 最后将值中的
\;替换为;,还原转义后的分号
方案2:手动字符遍历解析(更可靠)
对于复杂的转义场景,手动遍历字符比正则更可控,能处理所有边界情况。
解析步骤
初始化变量:
- 结果Map
resultMap - 当前键
currentKey,当前值缓冲区currentValue - 遍历索引
pos = 0,字符串长度len = input.length() - 状态标记
isKey = true(初始处于键的解析状态)
- 结果Map
循环遍历每个字符(以Java为例):
while (pos < len) { char c = input.charAt(pos); // 处理转义字符:跳过反斜杠,直接取后面的字符 if (c == '\\' && pos + 1 < len) { char nextChar = input.charAt(pos + 1); if (isKey) { currentKey += nextChar; } else { currentValue += nextChar; } pos += 2; continue; } // 切换到值状态:遇到未转义的等号且当前在键状态 if (c == '=' && isKey) { isKey = false; pos += 1; continue; } // 完成一个键值对:遇到未转义的分号且当前在值状态 if (c == ';' && !isKey) { resultMap.put(currentKey, currentValue); // 重置状态 currentKey = ""; currentValue = ""; isKey = true; pos += 1; continue; } // 普通字符,加入对应缓冲区 if (isKey) { currentKey += c; } else { currentValue += c; } pos += 1; } // 处理最后一个未以分号结尾的键值对(如果存在) if (!currentKey.isEmpty()) { resultMap.put(currentKey, currentValue); }
优势
- 直接处理转义逻辑,无需后续替换操作
- 能处理键中包含等号的极端场景(如果业务允许)
- 对空值、未填全键的场景兼容性更好
内容的提问来源于stack exchange,提问作者ui uk
相关产品推荐
相关产品推荐

