if语句中无法匹配反斜杠与竖杠字符的问题排查
SQL字符串反序列化转义字符处理异常
问题场景
原始SQL字符串片段:
(335, 'Anschutz 1710/1712', '<p>\r\n <a href=\"" onclick=\"window.open(this.href, \'\', \'resizable=no,status=no,location=no,toolbar=no,menubar=no,fullscreen=no,scrollbars=no,dependent=no\'); return false;\"><img alt=\"" src=\"" style=\"width: 780px; height: 659px;\" /></a></p>\r\n', 1, 17, '', '', '', '', 0, '', 0, 0, 88, '', 0),
尝试反序列化该字符串并去除转义字符时,使用if(character == '\\')匹配反斜杠,仅能捕获到this.href后的第二个\',之前的5个反斜杠全部被跳过。
现有C#代码
public static string[] RipASQLQuery(string data) { // Remove the SQL stuff var str = data.Replace("(", ""); str = str.Replace(")", ""); str = str.Replace(";", ""); var list = new List<string>(); int i = 0; bool inSubstring = false; bool escaped = false; foreach (var character in str.ToCharArray()) { if (list.Count < i + 1) { list.Add(""); } if (escaped) { // Ignore this character Console.WriteLine("Escaped " + character); escaped = false; continue; } if (inSubstring) { if (character == '\') inSubstring = false; list[i] += character; continue; } if(character == ('\\') { Console.WriteLine("Backslash!!"); escaped = true; continue; } else if (character == '\') { inSubstring = true; list[i] += character; continue; } else if(character == ',') { i++; continue; } else { list[i] += character; } } return list.ToArray(); }
尝试的无效操作
用str.Replace("\\", "|");将反斜杠替换为竖杠,得到以下字符串:
335, 'Anschutz 1710/1712', '<p>|r|n <a href=|"|" onclick=|"window.open(this.href, |'|', |'resizable=no,status=no,location=no,toolbar=no,menubar=no,fullscreen=no,scrollbars=no,dependent=no|' return false|"><img alt=|"|" src=|"|" style=|"width: 780px height: 659px|" /></a></p>|r|n', 1, 17, '', '', '', '', 0, '', 0, 0, 88, '', 0,
但仍在this.href后的第二个|'处出现解析异常。
问题根源与修复
核心问题
- 语法错误:代码中
character == '\'属于无效语法,C#中单引号需要转义为'\'',否则编译器无法识别。 - 逻辑错误:
- 处理转义时,当前逻辑直接忽略转义后的字符,实际应该将转义后的字符(如
'或")添加到结果中,而不是跳过。 - 在字符串内部时,遇到未转义的单引号才应该退出字符串模式;如果是转义后的单引号(即
\'),应该保留单引号并继续处于字符串模式。
- 处理转义时,当前逻辑直接忽略转义后的字符,实际应该将转义后的字符(如
修正后的代码
public static string[] RipASQLQuery(string data) { // 移除SQL包裹符号 var str = data.Replace("(", "").Replace(")", "").Replace(";", ""); var list = new List<string>(); int currentIndex = 0; bool inString = false; bool isEscaped = false; foreach (char c in str) { // 确保当前索引对应的列表项存在 if (list.Count <= currentIndex) { list.Add(string.Empty); } if (isEscaped) { // 转义状态下,直接添加当前字符并取消转义标记 list[currentIndex] += c; isEscaped = false; continue; } if (inString) { if (c == '\\') { // 遇到转义符,标记为转义状态 isEscaped = true; } else if (c == '\'') { // 遇到未转义的单引号,退出字符串模式 inString = false; list[currentIndex] += c; } else { // 普通字符直接添加 list[currentIndex] += c; } continue; } // 不在字符串模式下的逻辑 if (c == '\\') { isEscaped = true; } else if (c == '\'') { inString = true; list[currentIndex] += c; } else if (c == ',') { // 遇到逗号,切换到下一个字段 currentIndex++; } else { list[currentIndex] += c; } } // 移除末尾可能的空项(如果原字符串以逗号结尾) if (list.Count > currentIndex && string.IsNullOrWhiteSpace(list[currentIndex])) { list.RemoveAt(currentIndex); } return list.ToArray(); }
关键逻辑说明
- 转义处理:当遇到
\时标记isEscaped为true,下一个字符直接添加到结果,不再触发其他判断。 - 字符串模式切换:仅当处于字符串模式且遇到未转义的单引号时,才退出字符串模式;转义后的单引号会被正常保留。
- 语法修正:所有单引号判断都使用正确的转义写法
'\''。
内容的提问来源于stack exchange,提问作者UntoldTitan
相关产品推荐
相关产品推荐

