什么是regexp_replace SQL Server中的等效项

时间:2020-04-28 19:30:12

标签: sql-server oracle

我在Oracle中有这段代码,我需要将其转换为SQL Server才能获得相同的行为。我已经使用了REPLACE函数。似乎可行,但我只是想确定一下。

REGEXP_REPLACE(
                phonenumber, 
               '([[:digit:]]{3})([[:digit:]]{3})([[:digit:]]{4})', 
               '(\1)\2-\3'
               ) phonenumber

3 个答案:

答案 0 :(得分:1)

SQL Server不具有本机正则表达式支持。您将需要使用CLR(或在新的@Lukasz Szozda之一的注释中指出Language Extensions)。

如果我正确理解了正则表达式,尽管它与10位数字的字符串匹配,并将前3个分配给组1,然后将3分配给组2,最后4个分配给组3,然后在表达式{{1中使用反向引用}}

您可以使用内置的字符串函数执行以下操作

(\1)\2-\3

答案 1 :(得分:0)

您可以使用CLR编写SQL函数,该函数将包装标准dotnet正则表达式。我已经写过了,您可以使用它there。看起来像这样:

public boolean validateMobileNumber(long number) throws Exception {

    String num = Long.toString(number);

    String regex = "@\"^[7-9]{10}$";
    if (num.equals(regex))
        return true;
    else
        throw new Exception("Invalid Number");
}

答案 2 :(得分:0)

正如 Martin 在 his answer 中所说,SQL Server 没有内置的 RegEx 功能(虽然这里没有建议这样做,但要清楚:不,[...] 通配符 {{ 1}} 和 LIKE 不是 RegEx)。如果您的数据几乎没有变化,那么可以,您可以使用 T-SQL 函数的某种组合:PATINDEXREPLACESUBSTRINGLEFT、{{1} }、RIGHTCHARINDEXPATINDEX,也许还有其他一两个。

但是,如果数据/输入甚至具有中等程度的复杂性,那么内置的 T-SQL 函数充其量是繁琐的,最糟糕的是毫无用处。在这种情况下,可以通过 SQLCLR 执行实际的 RegEx(只要您不使用 Azure SQL 数据库单 DB 或通过 AWS RDS 的 SQL Server 2017+),这是(受限制的).NET 代码在 SQL Server 中运行。您可以自己编写代码/在 S.O. 上找到示例。或其他地方,或者尝试一个预先完成的库,例如我创建的库 SQL# (SQLsharp),它的免费版本包含几个 RegEx 函数。请注意,作为 .NET 的 SQLCLR 不是基于 POSIX 的 RegEx,因此不使用 POSIX character classes(意思是:您需要将 FORMATMESSAGE 用于“数字”而不是 {{1} }).

在这种特定情况下所需的复杂程度尚不清楚,因为问题中的示例代码暗示数据简单且统一(即 CONCAT),但 comment on the question 中显示的示例数据出现表示数据中可能有破折号和/或空格(即 \d)。

如果数据确实是统一的,那么坚持使用@MartinSmith 提供的纯T-SQL 解决方案。但是,如果数据足够复杂,那么请考虑下面的 RegEx 示例,使用在我的 SQL# 库的免费版本中找到的 SQLCLR 函数(如前所述),它可以轻松处理输入数据的 3 种变体以及更多:

[:digit:]

返回:

1112223333

RegEx 模式允许:

  • 0 或 1 xxx- xxx xxxx
  • 3 位十进制数字
  • 0 或 1 SELECT SQL#.RegEx_Replace4k(tmp.phone, N'\(?(\d{3})\)?[ .-]*(\d{3})[ .-]*(\d{4})', N'($1)$2-$3', -1, -- count (-1 == unlimited) 1, -- start at N'') -- RegEx options FROM (VALUES (N'8885551212'), (N'123- 456 7890'), (N'(777) 555- 4653') ) tmp([phone]);
  • 0 个或多个 (888)555-1212 (123)456-7890 (777)555-4653 ()
  • 3 位十进制数字
  • 0 个或多个 .-
  • 4 位十进制数字

注意

有人提到较新的语言扩展可能是比 SQLCLR 更好的选择。语言扩展允许通过 存储过程调用托管在 SQL Server 外部的 R/Python/Java 代码。正如 Tutorial: Search for a string using regular expressions (regex) in Java 页面所示,对于 SQL Server 中 RegEx 的许多/大多数用途来说,外部脚本实际上不是一个好的选择。主要问题是:

  1. 与 SQLCLR 不同,外部脚本的唯一接口是存储过程。这意味着您不能在查询(.- 等)中使用任何内联功能。
  2. 使用外部脚本,您可以传入查询,使用外部语言处理结果,然后传回静态结果集。这意味着编译后的代码现在必须更加专业化(即紧密耦合)到特定用途。更改查询使用 RegEx 的方式和/或返回哪些列现在需要编辑、编译、测试和部署 R/Python/Java 代码以及(协调!)T-SQL变化。

我敢肯定,在某些情况下,外部脚本绝对很棒,并且是比 SQLCLR 更好的选择。但它们肯定不适合使用 RegEx 的方式(与许多/大多数其他函数一样)的高度多样化且通常是临时性质的。