适用于:✅ 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));