正则匹配含等号值的字典元素时匹配错误的解决方法
这个问题很常见——当正则里用了贪婪匹配的.*时,遇到值里包含等号或者特殊字符就会“过度匹配”,把后面的内容也吞进去。我来帮你调整正则,完美解决这个问题:
修正后的正则表达式
--([^=]+)=([\s\S]*?)(?=\s*--|$)
逐部分解释为什么这么写:
--:精确匹配参数的起始标记(两个短横线)([^=]+):捕获键名(第一组)。[^=]表示匹配任意非等号字符,确保只捕获到第一个等号之前的键名,不会把值里的等号混进来=:匹配键和值之间的分隔等号([\s\S]*?):捕获值(第二组)。[\s\S]等价于匹配所有字符(包括换行、空格、特殊符号,解决了你值里有换行和特殊字符的问题);*?是非贪婪匹配,会尽可能少地匹配字符,直到触发后面的停止条件(?=\s*--|$):正向预查(不捕获内容),定义值的停止边界:要么是可选空格+下一个--参数起始,要么是字符串结尾。这样就能精准截断到下一个参数之前,不会把后面的参数内容包含进来
测试你的输入示例
拿你提供的输入字符串测试,这个正则会正确捕获到:
- 第一组:
key_a,第二组:value1 - 第一组:
key_b,第二组:value2 - ...
- 第一组:
key_e,第二组:-----BEGIN CERTIFICATE-----\nHYxCzAJBgNV--=B+AYT\AlVTM/QswCQYDVQQIDAJDQTE=RMA8GA1UEBwwIU2FuIEpvc2UxFTATBgNVBAoMDE51dGFuaXg\r
为什么原来的正则不行?
你原来的--(.*)=(.*[\w\s\n\Z\r]*)有两个核心问题:
- 第一个
(.*)是贪婪匹配,会尽可能多的匹配字符,甚至会跨过中间的等号,把多个键值对的部分内容都包含进来 - 第二组的
.*[\w\s\n\Z\r]*不仅冗余(.*已经包含这些字符),而且同样是贪婪匹配,会把后面的参数起始--也吞进去,导致匹配结果混乱
内容的提问来源于stack exchange,提问作者Aditya
相关产品推荐
相关产品推荐

