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

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', '&lt;p&gt;|r|n    &lt;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|"&gt;&lt;img alt=|"|" src=|"|" style=|"width: 780px height: 659px|" /&gt;&lt;/a&gt;&lt;/p&gt;|r|n', 1, 17, '', '', '', '', 0, '', 0, 0, 88, '', 0,

但仍在this.href后的第二个|'处出现解析异常。

问题根源与修复

核心问题

  1. 语法错误:代码中character == '\'属于无效语法,C#中单引号需要转义为'\'',否则编译器无法识别。
  2. 逻辑错误:
    • 处理转义时,当前逻辑直接忽略转义后的字符,实际应该将转义后的字符(如'或")添加到结果中,而不是跳过。
    • 在字符串内部时,遇到未转义的单引号才应该退出字符串模式;如果是转义后的单引号(即\'),应该保留单引号并继续处于字符串模式。

修正后的代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:44:49