適用於:✅ Microsoft Fabric 中的 SQL 分析端點與資料倉儲
正則表達式(regex)函式讓你能在 T-SQL 查詢中直接匹配複雜的文字模式並操作字串資料。 利用它們驗證格式、從半結構化文字中提取數值、計數模式出現,以及清理或遮罩資料,且不必將資料移出倉庫。
Note
正則表達式目前處於預覽階段。
倉庫與 SQL 分析端點支援 純量 正則表達式函式。 這些函式每個輸入資料列都會回傳一個值,因此你可以在 SELECT 清單、WHERE、JOIN、GROUP BY、ORDER BY 和 CASE 表達式中使用它們。
Note
倉庫中僅提供純量正則表達式函數。 表值函式 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 參數是 char 或 varchar 值,長度最多 30 個字元,用來設定相符的修飾符。 如果你提供矛盾的旗標,最後一個會勝出。 例如,'ic' 會產生區分大小寫的比對結果。
| Flag | Description |
|---|---|
c |
區分大小寫的比對。 此為預設值。 |
i |
不區分大小寫的比對。 |
m |
多行模式: ^ 並 $ 匹配每行的開頭與結尾,以及文本的開頭與結尾。 |
s |
讓我們匹配 . 換行字元 \n。 |
Considerations
- 該
string_expression參數接受字串類型。 支援大值(varchar(max)),最大可達 2 MB。 - 該
pattern_expression參數最大長度為 8,000 位元組。 - 正則表達式函式不會遵循定序規則。 匹配可能與其他字串比較不同,例如
LIKE。 要控制大小寫敏感度,請使用i和c標誌,而非依賴欄位定序。 更多資訊請參見 Data Warehouse collation。 -
REGEXP_LIKE回傳一個布林值,無法直接以欄位回傳。 若要將結果以欄位形式回傳,請將其包裹在CASE表達式中。
Examples
以下範例使用小型內嵌資料集,因此你可以在任何資料倉儲或 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));