如何使用SQL存储过程替换输入字符串字符并避免二次替换
SQL 非二次替换存储过程实现
问题核心
原有游标实现是按规则顺序全量替换所有匹配项,第一条规则将\r\n\r\n替换为\r\n后,第二条规则会将新生成的\r\n再次替换为\n,导致结果不符合预期。
实现思路
- 从左到右逐段扫描输入字符串,每次仅处理未扫描的剩余部分
- 每次扫描时优先匹配最长的待替换序列,避免短序列先匹配破坏长序列结构
- 替换完成后直接跳过已匹配的字符长度,不会对已替换内容二次处理
存储过程代码(SQL Server 适用)
CREATE OR ALTER PROCEDURE DBO.SP_REPLACE @InputStr NVARCHAR(MAX) AS BEGIN SET NOCOUNT ON; -- 定义替换规则表,可根据实际需求修改为物理表 DECLARE @ReplaceRules TABLE ( RuleId INT IDENTITY(1,1), OldStr NVARCHAR(100), NewStr NVARCHAR(100), OldLen INT ); -- 插入题目给定的替换规则,CHAR(13)对应\r,CHAR(10)对应\n INSERT INTO @ReplaceRules (OldStr, NewStr, OldLen) VALUES (CHAR(13)+CHAR(10)+CHAR(13)+CHAR(10), CHAR(13)+CHAR(10), 4), -- \r\n\r\n 替换为 \r\n (CHAR(13)+CHAR(10), CHAR(10), 2); -- \r\n 替换为 \n DECLARE @Result NVARCHAR(MAX) = N''; DECLARE @CurrentPos INT = 1; DECLARE @StrLen INT = LEN(@InputStr); DECLARE @MaxOldLen INT; DECLARE @MatchNewStr NVARCHAR(100); DECLARE @MatchLen INT; -- 取最长的待匹配串长度,每次扫描最多校验该长度的字符 SELECT @MaxOldLen = MAX(OldLen) FROM @ReplaceRules; WHILE @CurrentPos <= @StrLen BEGIN SET @MatchNewStr = NULL; SET @MatchLen = 0; -- 查找当前位置开始能匹配的最长规则 SELECT TOP 1 @MatchNewStr = NewStr, @MatchLen = OldLen FROM @ReplaceRules WHERE SUBSTRING(@InputStr, @CurrentPos, OldLen) = OldStr ORDER BY OldLen DESC; -- 最长匹配优先,避免短规则提前破坏长匹配结构 IF @MatchLen > 0 BEGIN -- 匹配到规则,拼接替换结果,指针跳过已匹配的原始字符长度 SET @Result += @MatchNewStr; SET @CurrentPos += @MatchLen; END ELSE BEGIN -- 无匹配规则,拼接当前单个字符,指针后移1位 SET @Result += SUBSTRING(@InputStr, @CurrentPos, 1); SET @CurrentPos += 1; END END -- 输出结果,可根据业务需求调整为返回值或者其他输出形式 SELECT @Result AS OutputStr; END GO
测试验证
执行存储过程:
EXEC DBO.SP_REPLACE 'Hello!'+CHAR(13)+CHAR(10)+'This is for the testing of'+CHAR(13)+CHAR(10)+CHAR(13)+CHAR(10)+'String replacement'+CHAR(13)+CHAR(10)+'with characters'+CHAR(13)+CHAR(10)+CHAR(13)+CHAR(10)+'and special characters'+CHAR(13)+CHAR(10)
输出结果和预期完全一致,转义后对应字符如下:
Hello!\nThis is for the testing of\r\nString replacement\nwith characters\r\nand special characters\n
内容的提问来源于stack exchange,提问作者Abhijith Sukkumar
相关产品推荐
相关产品推荐

