【问题标题】:SQL REPLACE with Multiple [0-9]SQL 替换为多个 [0-9]
【发布时间】:2022-01-22 14:17:50
【问题描述】:

我有一个字符串,我想替换一组数字。
该字符串包含一组数字(和几个字母)。 'A12 456 1 65 7944' 我想用“xxx”替换3个数字的组,用“zzzz”替换4个数字的组

我认为像 REPLACE(@str, '%[0-9][0-9][0-9]%', 'xxx') 这样的东西会起作用,但事实并非如此。我什至无法让'%[0-9]%' 替换任何东西。

如果 REPLACE 不合适,我该如何替换数字组?

【问题讨论】:

  • 根据文档,替换不接受通配符。
  • @DaleK 关于如何在没有 REPLACE 的情况下完成此任务的建议?
  • 不是真的,它不是 SQL 擅长的......如果你必须在 SQL Server 中执行它,请尝试使用 CLR 函数。
  • 我想我可以使用 PATINDEX 和 STUFF
  • 要轻松做到这一点,您需要一个正则表达式替换,遗憾的是 SQL Server 不支持开箱即用。

标签: sql sql-server tsql replace


【解决方案1】:

请尝试以下基于 XML 和 XQuery 的解决方案。

值得注意的点:

  1. 我们在 CROSS APPLY 子句中将输入字符串标记为 XML。
  2. XQuery 的 FLWOR 表达式正在检查数字整数值 特定长度,然后用替换字符串替换。
  3. XQuery .value() 方法返回最终结果。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, tokens VARCHAR(MAX));
INSERT INTO @tbl (tokens) VALUES
('A12 456 1 65 7944');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = SPACE(1);

SELECT t.* 
    , c.query('
    for $x in /root/r/text()
    return if (xs:int($x) instance of xs:int and string-length($x)=3) then "xxx"
        else if (xs:int($x) instance of xs:int and string-length($x)=4) then "zzzz"
        else data($x)
    ').value('.', 'VARCHAR(MAX)') AS Result
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
        REPLACE(tokens, @separator, ']]></r><r><![CDATA[') + 
        ']]></r></root>' AS XML)) AS t1(c);

输出

+----+-------------------+-------------------+
| ID |      tokens       |      Result       |
+----+-------------------+-------------------+
|  1 | A12 456 1 65 7944 | A12 xxx 1 65 zzzz |
+----+-------------------+-------------------+

【讨论】:

  • 现在这很漂亮。性能如何?
  • XQuery 是 MS SQL Server 中隐藏的瑰宝。我希望 OP 将尝试提出的解决方案,并报告结果,包括性能。
  • 您有关于如何使用 XQuery 的很好的参考资料吗?我通常不喜欢它,因为人们用它做什么,而大多数人使用它的方式实际上很糟糕。我认为您的解决方案非常聪明,我将使用您的好代码进行一些性能测试。如果成功了,你可能让我有点转变了。
  • 这是一个很好的免费 XQuery 培训:altova.com/training/xquery3
  • @JeffModen,我最近在 LinkedIn 上给你发了几条消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 2020-12-29
  • 2014-08-11
  • 2019-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多