Corresponder padrões com expressões regulares

Concluído

O processamento de texto em bancos de dados geralmente requer correspondência de padrões que vai além do que o LIKE operador pode manipular. Expressões regulares fornecem uma sintaxe padronizada para correspondência complexa de padrões, validação e transformação de texto. Os bancos de dados SQL Server 2025 e SQL no Microsoft Fabric incluem suporte a expressões regulares por meio de novas funções T-SQL.

Considere cenários onde LIKE fica aquém: validar endereços de email com o formato adequado, extrair números de telefone independentemente das variações de formatação, localizar códigos de produto que seguem convenções de nomenclatura específicas ou detectar padrões como caracteres consecutivos repetidos. O LIKE operador dá suporte apenas a caracteres curinga simples (% para qualquer caractere, _ para um único caractere), que não podem expressar esses padrões complexos.

Expressões regulares resolvem essas limitações fornecendo uma linguagem de padrão avançado. Com regex, você pode combinar intervalos de caracteres específicos, exigir contagens exatas de repetição, usar alternância (combinar este OU aquele) e capturar partes do texto combinado para extração ou substituição. Depois de aprender a sintaxe de expressões regulares, você poderá aplicá-las em várias linguagens e ferramentas de programação—os padrões que você escreve para o SQL Server funcionam de forma semelhante em Python, JavaScript e utilitários de linha de comando.

Entender as noções básicas de expressão regular

Expressões regulares (regex) usam uma sintaxe padrão para descrever padrões de texto. Antes de aprender as funções do SQL Server, vamos examinar estes componentes regex comuns:

Padrão DESCRIÇÃO Exemplo de correspondência
. Qualquer caractere único a.c corresponde a "abc", "a1c"
* Zero ou mais ocorrências do anterior ab*c corresponde a "ac","abc","abbc"
+ Um ou mais dos anteriores ab+c corresponde a "abc","abbc", mas não "ac"
? Zero ou um dos anteriores colou?r corresponde a "color", "colour"
^ Início da string ^Hello corresponde a cadeias de caracteres começando com "Hello"
$ Fim da cadeia de caracteres world$ corresponde a cadeias de caracteres que terminam com "mundo"
[abc] Classe de personagem [aeiou] corresponde a qualquer vogal
[^abc] Classe negada [^0-9] corresponde a nondigits
\d Dígito (0-9) \d{3} corresponde a três dígitos
\w Caractere do Word \w+ corresponde a caracteres de palavra
{n} Exatamente n ocorrências \d{4} corresponde a exatamente quatro dígitos
{n,m} Entre ocorrências de n e m \d{2,4} corresponde de 2 a 4 dígitos

Observação

As funções de expressão regular do SQL Server usam a sintaxe regex padrão ECMAScript . Essa é a mesma sintaxe usada em JavaScript e em muitas outras linguagens de programação, tornando os padrões portáteis entre tecnologias.

Corresponder padrões com REGEXP_LIKE

REGEXP_LIKE retornará 1 (true) se uma cadeia de caracteres corresponder a um padrão de expressão regular ou 0 (false) se não o fizer. Use essa função em WHERE cláusulas para filtrar linhas com base em padrões complexos:

-- 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;

Validar formatos de dados:

-- 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;

Use correspondência sem distinção entre maiúsculas e minúsculas com o parâmetro do sinalizador.

-- 'i' flag enables case-insensitive matching
SELECT Name
FROM SalesLT.Product
WHERE REGEXP_LIKE(Name, 'frame', 'i') = 1;

Dica

Use REGEXP_LIKE para validação e filtragem. É mais eficiente do que extrair subcadeias quando você só precisa saber se existe um padrão.

Substituir texto por REGEXP_REPLACE

REGEXP_REPLACE localiza todas as ocorrências de um padrão e as substitui por uma cadeia de caracteres especificada. Essa função é útil para limpeza e padronização de dados:

-- 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;

Os exemplos a seguir demonstram como usar grupos de captura com referências anteriores:

-- 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

Os exemplos a seguir demonstram como limpar e normalizar dados:

-- 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;

Extrair subcadeias de caracteres com REGEXP_SUBSTR

REGEXP_SUBSTR extrai a parte de uma cadeia de caracteres que corresponde a um padrão de expressão regular. Use-o para extrair elementos de dados específicos de texto não estruturado, como os seguintes exemplos:

-- 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;

O exemplo a seguir demonstra a assinatura da função, que inclui parâmetros para grupos de ocorrência e captura:

REGEXP_SUBSTR(source, pattern, start_position, occurrence, flags, capture_group)

Localizar posições de padrões com REGEXP_INSTR

REGEXP_INSTR retorna a posição inicial de uma correspondência de padrão dentro de uma cadeia de caracteres. Retorna 0 se nenhuma correspondência for encontrada, como os seguintes exemplos:

-- 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;

Contar ocorrências de padrão com REGEXP_COUNT

REGEXP_COUNT retorna o número de vezes que um padrão aparece em uma cadeia de caracteres. Os exemplos a seguir ilustram seu uso:

-- 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;

Dividir cadeias de caracteres com REGEXP_SPLIT_TO_TABLE

REGEXP_SPLIT_TO_TABLE é uma função com valor de tabela que divide uma cadeia de caracteres em linhas com base em um padrão delimitador:

-- 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, '[,;|]');

Você pode combinar REGEXP_SPLIT_TO_TABLE com outras consultas usando 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;

Retorne todas as correspondências com REGEXP_MATCHES

REGEXP_MATCHES é uma função com valor de tabela que retorna todas as correspondências de padrão como linhas separadas:

-- 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

Importante

As funções de expressão regular estão disponíveis no SQL Server 2025 e nos bancos de dados SQL do Microsoft Fabric. Para versões anteriores do SQL Server, considere o uso de funções CLR ou processamento de camada de aplicativo para operações regex complexas.

Para obter mais informações sobre funções de expressão regular, consulte Expressões regulares.