C#正则捕获重复组问题:修复JSON字符串未转义双引号
我明白你遇到的问题了——处理JSON里未转义的双引号本来就头疼,还要面对key1内部键值对数量不固定的情况,固定分组的正则肯定行不通。咱们换个思路,用嵌套替换的方式来解决:先定位到key1对应的整个对象,再在这个对象内部批量处理所有值里的未转义双引号。
解决思路
核心是两步走:
- 精准定位
"key1":{...}这个对象块,不管里面有多少键值对; - 在这个对象内部,针对每个键值对的值部分,把未转义的双引号替换成转义后的
\"。
C# 代码实现
using System; using System.Text.RegularExpressions; class Program { static void Main() { // 你的日志文本 string logText = "\"key1\":{ \"v1\":\"M.V. \"1002 xyz\" V.089E\", \"v2\":\"M.V. \"tr34 abc\" V.089E\" }"; // 第一步:匹配key1对应的整个对象,捕获前后标记和内部内容 var outerRegex = new Regex(@"(""key1"":\s*\{)(.*?)(\})", RegexOptions.Singleline); // 执行替换,用MatchEvaluator处理内部内容 string fixedJson = outerRegex.Replace(logText, match => { string prefix = match.Groups[1].Value; // "key1":{ string innerContent = match.Groups[2].Value; // 内部的键值对内容 string suffix = match.Groups[3].Value; // } // 第二步:处理内部的每个键值对,转义值里的未转义双引号 string processedInner = Regex.Replace(innerContent, @"(""[^""]+"":\s*"")(.*?)(?<!\\)(""|\Z)", innerMatch => { string keyPart = innerMatch.Groups[1].Value; // "v1": " string valueContent = innerMatch.Groups[2].Value; // M.V. "1002 xyz" V.089E string endQuote = innerMatch.Groups[3].Value; // " // 替换值内容里所有未被转义的双引号 string escapedValue = Regex.Replace(valueContent, @"(?<!\\)""", @"\"""); return keyPart + escapedValue + endQuote; }, RegexOptions.Singleline); return prefix + processedInner + suffix; }); Console.WriteLine(fixedJson); } }
代码说明
外层正则:
(@"(""key1"":\s*\{)(.*?)(\})", RegexOptions.Singleline)RegexOptions.Singleline让.匹配换行符,适配日志里可能存在的换行;- 捕获三个组:
"key1":{前缀、内部键值对内容、}后缀,确保只处理key1的对象。
内层正则:
(@"(""[^""]+"":\s*"")(.*?)(?<!\\)(""|\Z)", RegexOptions.Singleline)- 捕获每个键值对的三部分:键的标记(比如
"v1": ")、值的原始内容、结尾的双引号; (?<!\\)是负向断言,确保只匹配未被转义的双引号,避免把已经转义的\"再次转义成\\"。
- 捕获每个键值对的三部分:键的标记(比如
值内容转义:
Regex.Replace(valueContent, @"(?<!\\)""", @"\""")专门处理值里的未转义双引号,把它们替换成\"。
测试结果
运行代码后,输入的日志文本会被转换成合法的JSON:
"key1":{ "v1":"M.V. \"1002 xyz\" V.089E", "v2":"M.V. \"tr34 abc\" V.089E" }
这样不管key1里面有多少个键值对,都能自动处理,不用写固定数量的分组。
内容的提问来源于stack exchange,提问作者SD13
相关产品推荐
相关产品推荐

