在Fabric Data Warehouse中使用正则表达式函数

适用于:✅ Microsoft Fabric 中的 SQL 分析终结点和仓库

正则表达式(正则表达式)函数可以让你匹配复杂的文本模式,并在 T-SQL 查询中直接操作字符串数据。 用它们验证格式、从半结构化文本中提取值、计数模式出现次数,以及清理或屏蔽数据而无需将其移出仓库。

注释

正则表达式目前处于预览阶段。

Warehouse 和 SQL 分析端点支持 标量 正则表达式函数。 这些函数每个输入行返回一个值,因此你可以在 SELECT 列表、WHERE、JOIN、GROUP BY、ORDER BY 和 CASE 表达式中使用它们。

注释

仓库中仅支持标量正则表达式函数。 表值函数 REGEXP_MATCHES 和 REGEXP_SPLIT_TO_TABLE 不被支持。

支持的函数

函数 返回类型 Description
REGEXP_LIKE 布尔 表示文本输入是否符合正则表达式模式。 将其用作谓词,例如在 WHERE 子句或 CASE 表达式中。
REGEXP_REPLACE 字符串表达式 返回源字符串,将其中与正则表达式模式匹配的内容替换为替换字符串。 如果没有匹配,返回原始字符串。
REGEXP_SUBSTR 字符串表达式 返回第 n次与正则表达式模式匹配的子串。
REGEXP_INSTR int 返回匹配子串的起始或结束位置。
REGEXP_COUNT int 返回正则表达式模式在字符串中出现的次数。

Syntax

REGEXP_LIKE ( string_expression, pattern_expression [ , flags ] )

REGEXP_REPLACE ( string_expression, pattern_expression [ , string_replacement [ , start [ , occurrence [ , flags ] ] ] ] )

REGEXP_SUBSTR ( string_expression, pattern_expression [ , start [ , occurrence [ , flags [ , group ] ] ] ] )

REGEXP_INSTR ( string_expression, pattern_expression [ , start [ , occurrence [ , return_option [ , flags [ , group ] ] ] ] ] )

REGEXP_COUNT ( string_expression, pattern_expression [ , start [ , flags ] ] )

关于每个参数的完整描述,请参见 支持函数中的链接函数参考。

Flags

可选 flags 参数是最长 30 个字符的 char 或 varchar 值,用于设置匹配的修饰符。 如果你提供相互矛盾的标志,最后一个生效。 例如,会产生 'ic' 大小写相关的匹配。

Flag Description
c 区分大小写的匹配。 这是默认值。
i 不区分大小写的匹配。
m 多行模式:^ 和 $ 都匹配每行的开头和结尾,以及文本的开头和结尾。
s 我们匹配 . 换行字符 \n。

Considerations

  • 该 string_expression 参数接受字符字符串类型。 最大为 2 MB 的大值(varchar(max))受支持。
  • 该 pattern_expression 参数支持最大长度为8,000字节。
  • 正则表达式函数不遵守排序规则。 匹配可能与其他字符串比较不同,如 LIKE。 为了控制大小写敏感性,使用 i 和 c 标志,而不是依赖列排序规则。 有关详细信息,请参阅 数据仓库排序规则。
  • REGEXP_LIKE 返回布尔值,不能直接以列形式返回。 要将结果作为一列返回,可以用 CASE 表达式包裹。

示例

以下示例使用一个小型内联数据集,因此你可以在任何仓库或SQL分析端点中运行。

A. 筛选与某个模式匹配的行

在REGEXP_LIKE子句中使用WHERE,以仅返回具有有效电子邮件地址格式的行。

SELECT CustomerId, Email
FROM (VALUES
        (1, 'anna@contoso.com'),
        (2, 'not-an-email'),
        (3, 'Bob.Smith@Fabrikam.org')
     ) AS c (CustomerId, Email)
WHERE REGEXP_LIKE(Email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$');

要以列形式返回匹配结果,可以将 REGEXP_LIKE 包装在一个 CASE 表达式中:

SELECT Email,
       CASE WHEN REGEXP_LIKE(Email, '@contoso\.com$', 'i') THEN 'Internal' ELSE 'External' END AS EmailType
FROM (VALUES ('anna@CONTOSO.com'), ('bob@fabrikam.org')) AS c (Email);

B. 从文本中提取一个值

使用 REGEXP_SUBSTR 从自由文本注释中提取格式为 ORD- 后跟数字的第一个订单号。

SELECT Comment,
       REGEXP_SUBSTR(Comment, 'ORD-\d+') AS OrderNumber
FROM (VALUES
        ('Customer called about ORD-10293 and ORD-10311.'),
        ('No order referenced.')
     ) AS t (Comment);

如果只提取部分匹配内容,可以使用捕获组。 以下查询返回每个电子邮件地址的域名:

SELECT REGEXP_SUBSTR(Email, '@(.+)$', 1, 1, 'c', 1) AS EmailDomain
FROM (VALUES ('anna@contoso.com'), ('bob@fabrikam.org')) AS c (Email);

C. 统计模式出现次数

使用 REGEXP_COUNT 来计算每个字符串中出现的数字数量。

SELECT Comment,
       REGEXP_COUNT(Comment, '\d+') AS NumberCount
FROM (VALUES
        ('Shipped 3 boxes on 12 May, invoice 4471.'),
        ('No numbers here.')
     ) AS t (Comment);

D. 找到匹配的位置

使用 REGEXP_INSTR 查找第一组数字的起始位置和结束位置。

SELECT ProductCode,
       REGEXP_INSTR(ProductCode, '\d+')             AS FirstDigitStart,
       REGEXP_INSTR(ProductCode, '\d+', 1, 1, 1)    AS FirstDigitEnd
FROM (VALUES ('BK-R93R-62'), ('HL-U509')) AS p (ProductCode);

E. 清理和掩蔽数据

用 REGEXP_REPLACE 使用捕获组来标准化电话号码,并遮蔽除最后四位数字外的所有数字。

SELECT Phone,
       REGEXP_REPLACE(Phone, '^(\d{3})-(\d{3})-(\d{4})$', '(\1) \2-\3') AS FormattedPhone,
       REGEXP_REPLACE(Phone, '^\d{3}-\d{3}', '***-***')               AS MaskedPhone
FROM (VALUES ('425-555-0187'), ('206-555-0142')) AS c (Phone);

以下查询将重复的空白压缩为一个空白:

SELECT REGEXP_REPLACE('Fabric    Data   Warehouse', '\s+', ' ') AS CleanText;

F. 按提取值进行分组和聚合

由于函数是标量的,你可以将它们用于 GROUP BY 子句。 以下查询是按电子邮件域名计算客户数量。

SELECT LOWER(REGEXP_SUBSTR(Email, '@(.+)$', 1, 1, 'c', 1)) AS EmailDomain,
       COUNT(*) AS Customers
FROM (VALUES
        ('anna@contoso.com'),
        ('bob@Contoso.com'),
        ('chris@fabrikam.org')
     ) AS c (Email)
GROUP BY LOWER(REGEXP_SUBSTR(Email, '@(.+)$', 1, 1, 'c', 1));