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

SQL Server 2016+:查找不在单引号或方括号内的首个", --"位置

解法:仅用SELECT语句查找目标位置

可以通过递归CTE遍历字符串状态,结合字符位置匹配来实现需求,具体SQL如下:

WITH StringCTE AS (
    -- 初始化:处理第一个字符的状态
    SELECT
        string,
        desired_pos,
        1 AS pos,
        SUBSTRING(string, 1, 1) AS curr_char,
        CASE WHEN SUBSTRING(string, 1, 1) = '''' THEN 1 ELSE 0 END AS in_quote,
        CASE WHEN SUBSTRING(string, 1, 1) = '[' THEN 1 ELSE 0 END AS in_bracket,
        SUBSTRING(string, 1, 1) AS prev_char
    FROM (VALUES 
        (N'''a, --''[, --], --[, --]', 14),
        (N'[a, --b]aaaaaaa_ , --'', --''', 18)
    ) t(string, desired_pos)
    UNION ALL
    -- 递归遍历后续每个字符,更新状态
    SELECT
        s.string,
        s.desired_pos,
        s.pos + 1 AS pos,
        SUBSTRING(s.string, s.pos + 1, 1) AS curr_char,
        -- 处理单引号状态:仅非连续单引号才切换状态(连续''视为转义)
        CASE
            WHEN s.in_quote = 1 THEN
                CASE WHEN SUBSTRING(s.string, s.pos + 1, 1) = '''' AND s.prev_char <> '''' THEN 0 ELSE 1 END
            ELSE
                CASE WHEN SUBSTRING(s.string, s.pos + 1, 1) = '''' AND s.prev_char <> '''' THEN 1 ELSE 0 END
        END AS in_quote,
        -- 处理方括号状态:遇到[进入,遇到]退出
        CASE
            WHEN s.in_bracket = 1 THEN
                CASE WHEN SUBSTRING(s.string, s.pos + 1, 1) = ']' THEN 0 ELSE 1 END
            ELSE
                CASE WHEN SUBSTRING(s.string, s.pos + 1, 1) = '[' THEN 1 ELSE 0 END
        END AS in_bracket,
        SUBSTRING(s.string, s.pos + 1, 1) AS prev_char
    FROM StringCTE s
    WHERE s.pos < LEN(s.string)
),
DashPositions AS (
    -- 递归找出所有`, --`的起始位置
    SELECT
        string,
        desired_pos,
        CHARINDEX(', --', string, 1) AS dash_pos
    FROM (VALUES 
        (N'''a, --''[, --], --[, --]', 14),
        (N'[a, --b]aaaaaaa_ , --'', --''', 18)
    ) t(string, desired_pos)
    WHERE CHARINDEX(', --', string, 1) > 0
    UNION ALL
    SELECT
        dp.string,
        dp.desired_pos,
        CHARINDEX(', --', dp.string, dp.dash_pos + 1) AS dash_pos
    FROM DashPositions dp
    WHERE CHARINDEX(', --', dp.string, dp.dash_pos + 1) > 0
),
ValidPositions AS (
    -- 筛选出未被引号/方括号包裹的`, --`位置
    SELECT
        dp.string,
        dp.desired_pos,
        dp.dash_pos
    FROM DashPositions dp
    WHERE NOT EXISTS (
        SELECT 1
        FROM StringCTE sc
        WHERE sc.string = dp.string
          AND sc.pos BETWEEN dp.dash_pos AND dp.dash_pos + 3 -- 覆盖`, --`的4个字符位置
          AND (sc.in_quote = 1 OR sc.in_bracket = 1)
    )
)
-- 取每个字符串的第一个有效位置
SELECT
    string,
    desired_pos,
    MIN(dash_pos) AS actual_pos
FROM ValidPositions
GROUP BY string, desired_pos;

逻辑说明

  1. StringCTE:逐个字符遍历字符串,跟踪当前是否处于单引号内或方括号内。单引号仅在非连续出现时切换状态(连续两个'视为转义字符,不改变状态);方括号遇到[进入包裹状态,遇到]退出。
  2. DashPositions:递归查找字符串中所有, --的起始位置。
  3. ValidPositions:检查每个, --的4个字符(逗号、空格、两个减号)是否都不在引号或方括号包裹范围内,筛选出符合条件的位置。
  4. 最后通过MIN(dash_pos)获取每个字符串的首个有效位置。

注意事项

  • 如果字符串中不存在目标, --,actual_pos会返回NULL,可根据需求用ISNULL处理。
  • 当前逻辑未处理方括号嵌套(如[[a,b]])的场景,若需要支持嵌套,需调整方括号的状态判断逻辑。
  • 单引号转义逻辑符合SQL字符串的转义规则(连续两个'表示一个实际的')。

内容的提问来源于stack exchange,提问作者Mike S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:50:23