Сопоставление шаблонов с регулярными выражениями
Подсказка
Дополнительные сведения см. на вкладке "Текст и изображения ".
Обработка текста в базах данных часто требует сопоставления шаблонов, которые выходят за рамки того, что LIKE может обрабатывать оператор. Регулярные выражения предоставляют стандартный синтаксис для сложного сопоставления шаблонов, проверки и преобразования текста. Базы данных SQL Server 2025 и SQL в Microsoft Fabric включают поддержку регулярных выражений с помощью новых функций T-SQL.
Рассмотрим сценарии, в которых LIKE не справляется: когда нужно проверить адрес электронной почты на соответствие правильному формату, извлечь номера телефонов независимо от вариантов их форматирования, найти коды продуктов, соответствующие определённым правилам именования, или обнаружить шаблоны, такие как повторяющиеся подряд символы. Оператор LIKE поддерживает только простые подстановочные знаки (% для любых символов _ , для одного символа), которые не могут выразить эти сложные шаблоны.
Регулярные выражения решают эти ограничения, предоставляя широкий язык шаблонов. С помощью регулярных выражений можно сопоставить определенные диапазоны символов, требовать точное количество повторений, использовать чередование (соответствовать этому ИЛИ тому), а также захватывать части сопоставленного текста для извлечения или замены. После изучения синтаксиса регулярных выражений его можно применить ко многим языкам и средствам программирования. Шаблоны, которые вы пишете для SQL Server, работают аналогично в служебных программах Python, JavaScript и командной строки.
Основные сведения об основах регулярных выражений
Регулярные выражения (regex) используют синтаксис шаблона для описания текстовых шаблонов. Прежде чем узнать о функциях SQL Server, ознакомьтесь с этими общими компонентами regex:
| Рисунок | Description | Пример сопоставления |
|---|---|---|
. |
Любой один символ |
a.c соответствует "abc", "a1c" |
* |
Ноль или более повторений последующего элемента |
ab*c соответствует "ac", "abc", "abbc" |
+ |
Одно или несколько предыдущих |
ab+c соответствует "abc", "abbc" , но не "ac" |
? |
Ноль или одно из предшествующих элементов |
colou?r соответствует "цвет", "цвет" |
^ |
Начало строки |
^Hello соответствует строкам, начиная с "Hello" |
$ |
Конец строки |
world$ соответствует строкам, заканчивающимися "world" |
[abc] |
Класс персонажа |
[aeiou] соответствует любой гласной |
[^abc] |
Отрицательный класс |
[^0-9] соответствует нецифровым символам |
\d |
Цифра (0-9) |
\d{3} соответствует трем цифрам |
\w |
Символ Word |
\w+ соответствует символам слова |
{n} |
Точное количество вхождений n |
\d{4} соответствует ровно четыре цифры |
{n,m} |
От n до m вхождений |
\d{2,4} соответствует 2–4 цифрам |
Замечание
Функции регулярного выражения SQL Server используют стандартный синтаксис regex ECMAScript . Этот скрипт является одинаковым синтаксисом, используемым в JavaScript и многих других языках программирования, что делает шаблоны переносимыми между технологиями.
Сопоставление шаблонов с REGEXP_LIKE
REGEXP_LIKE возвращает значение 1 (true), если строка соответствует шаблону регулярного выражения, или значение 0 (false), если это не так. Используйте эту функцию в WHERE предложениях для фильтрации строк на основе сложных шаблонов:
-- Find customers with email addresses from specific domains
SELECT CustomerID, FirstName, LastName, EmailAddress
FROM SalesLT.Customer
WHERE REGEXP_LIKE(EmailAddress, '@(contoso|adventure-works|fabrikam)\.com$') = 1;
Проверка форматов данных:
-- Find valid US phone numbers (various formats)
SELECT CustomerID, Phone
FROM SalesLT.Customer
WHERE REGEXP_LIKE(Phone, '^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$') = 1;
-- Validate product numbers match expected format (XX-XXXX)
SELECT ProductID, ProductNumber, Name
FROM SalesLT.Product
WHERE REGEXP_LIKE(ProductNumber, '^[A-Z]{2}-[A-Z0-9]{4,6}$') = 1;
Используйте регистронезависимое сопоставление с использованием флагов:
-- 'i' flag enables case-insensitive matching
SELECT Name
FROM SalesLT.Product
WHERE REGEXP_LIKE(Name, 'frame', 'i') = 1;
Подсказка
Используется REGEXP_LIKE для проверки и фильтрации. Это более эффективно, чем извлечение подстроок, если необходимо только знать, существует ли шаблон.
Замените текст на REGEXP_REPLACE
REGEXP_REPLACE находит все вхождения шаблона и заменяет их указанной строкой. Эта функция полезна для очистки и стандартизации данных:
-- Standardize phone numbers to (XXX) XXX-XXXX format
SELECT
Phone AS OriginalPhone,
REGEXP_REPLACE(
REGEXP_REPLACE(Phone, '[^\d]', ''), -- First remove all non-digits
'^(\d{3})(\d{3})(\d{4})$',
'($1) $2-$3'
) AS StandardizedPhone
FROM SalesLT.Customer
WHERE Phone IS NOT NULL;
В следующих примерах показано, как использовать группы записи с обратными ссылками:
-- Swap first and last name
DECLARE @name NVARCHAR(100) = 'Smith, John';
SELECT REGEXP_REPLACE(@name, '^(\w+),\s*(\w+)$', '$2 $1') AS SwappedName;
-- Returns: John Smith
-- Mask credit card numbers (show last 4 digits only)
DECLARE @card NVARCHAR(20) = '4532-1234-5678-9012';
SELECT REGEXP_REPLACE(@card, '\d(?=[\d-]{4,})', '*') AS MaskedCard;
-- Returns: ****-****-****-9012
В следующих примерах показано, как очистить и нормализовать данные:
-- Remove extra whitespace (multiple spaces to single space)
SELECT REGEXP_REPLACE(Description, '\s+', ' ') AS CleanedDescription
FROM Products;
-- Remove HTML tags
SELECT REGEXP_REPLACE(HtmlContent, '<[^>]+>', '') AS PlainText
FROM WebPages;
Извлечение подстроок с помощью REGEXP_SUBSTR
REGEXP_SUBSTR извлекает часть строки, которая соответствует шаблону регулярного выражения. Используйте его для извлечения определенных элементов данных из неструктурированного текста, как показано в следующих примерах:
-- Extract domain from email address
SELECT
EmailAddress,
REGEXP_SUBSTR(EmailAddress, '@(.+)$', 1, 1, '', 1) AS Domain
FROM SalesLT.Customer
WHERE EmailAddress IS NOT NULL;
-- Extract the first number from a string
SELECT
ProductNumber,
REGEXP_SUBSTR(ProductNumber, '\d+') AS FirstNumber
FROM SalesLT.Product;
В следующем примере показана сигнатура функции, которая включает параметры для групп вхождения и записи:
REGEXP_SUBSTR(source, pattern, start_position, occurrence, flags, capture_group)
Поиск позиций шаблонов с помощью REGEXP_INSTR
REGEXP_INSTR возвращает начальную позицию сопоставления шаблона в строке. Возвращает значение 0, если совпадение не найдено, например в следующих примерах:
-- Find position of first digit in product number
SELECT
ProductNumber,
REGEXP_INSTR(ProductNumber, '\d') AS FirstDigitPosition
FROM SalesLT.Product;
-- Find position of email domain
SELECT
EmailAddress,
REGEXP_INSTR(EmailAddress, '@') AS AtPosition,
REGEXP_INSTR(EmailAddress, '\.[a-z]+$', 1, 1, 0, 'i') AS TldPosition
FROM SalesLT.Customer
WHERE EmailAddress IS NOT NULL;
Подсчет вхождений шаблонов с помощью REGEXP_COUNT
REGEXP_COUNT возвращает количество раз, когда шаблон отображается в строке. В следующих примерах показано его использование:
-- Count words in a description
SELECT
Name,
REGEXP_COUNT(Name, '\w+') AS WordCount
FROM SalesLT.Product;
-- Count vowels in product names
SELECT
Name,
REGEXP_COUNT(Name, '[aeiou]', 1, 'i') AS VowelCount
FROM SalesLT.Product;
-- Find products with multiple numbers in their name
SELECT Name
FROM SalesLT.Product
WHERE REGEXP_COUNT(Name, '\d+') > 1;
Разделение строк с помощью REGEXP_SPLIT_TO_TABLE
REGEXP_SPLIT_TO_TABLE — это табличная функция, которая разбивает строку на строки на основе шаблона разделителя:
-- Split comma-separated values
DECLARE @tags NVARCHAR(200) = 'sql,database,azure,analytics';
SELECT value AS Tag
FROM REGEXP_SPLIT_TO_TABLE(@tags, ',');
-- Split on multiple delimiters (comma, semicolon, or pipe)
DECLARE @data NVARCHAR(200) = 'apple,banana;cherry|date';
SELECT value AS Fruit
FROM REGEXP_SPLIT_TO_TABLE(@data, '[,;|]');
Вы можете объединить REGEXP_SPLIT_TO_TABLE с другими запросами с помощью CROSS APPLY:
-- Assuming Products table has a Tags column with comma-separated values
SELECT
p.ProductID,
p.Name,
t.value AS Tag
FROM Products AS p
CROSS APPLY REGEXP_SPLIT_TO_TABLE(p.Tags, ',\s*') AS t;
Верните все совпадения с REGEXP_MATCHES
REGEXP_MATCHES — это функция с табличным значением, которая возвращает все совпадения шаблонов в виде отдельных строк:
-- Find all numbers in a string
DECLARE @text NVARCHAR(200) = 'Order 12345 contains 3 items totaling $99.99';
SELECT match_value, match_index
FROM REGEXP_MATCHES(@text, '\d+\.?\d*');
-- Returns: 12345, 3, 99.99
Это важно
Функции регулярных выражений доступны в SQL Server 2025 и SQL-базах данных в Microsoft Fabric. Для более ранних версий SQL Server рассмотрите возможность использования функций общеязыковой среды выполнения (CLR) или обработки на уровне приложения для сложных операций с регулярными выражениями.
Дополнительные сведения о функциях регулярного выражения см. в разделе "Регулярные выражения".