9.7. Correspondência de padrões #

9.7.1. LIKE
9.7.2. Expressões regulares SIMILAR TO
9.7.3. Expressões regulares POSIX

Existem três abordagens distintas para correspondência de padrões fornecidas pelo PostgreSQL: o operador LIKE tradicional do SQL, o operador mais recente SIMILAR TO (adicionado no SQL:1999), e as expressões regulares no estilo POSIX. [59] [60] Além dos operadores básicos tipo esta cadeia de caracteres corresponde a este padrão?, estão disponíveis funções para extrair ou substituir sub-cadeias de caracteres usando correspondência, e para dividir uma cadeia de caracteres nas posições onde há correspondência.

Dica

Havendo necessidade de correspondência de padrão que vão além disso, deve ser considerado o desenvolvimento de uma função definida pelo usuário em Perl ou Tcl.

Cuidado

Embora a maioria das procuras através de expressões regulares possa ser executada muito rapidamente, podem ser criadas expressões regulares que usam quantidades ilimitadas de tempo e memória para serem processadas. Tenha cuidado ao acolher expressões regulares vindas de fontes hostis. Se precisar fazer isto, é recomendável impor um tempo limite ao comando.

As procuras que usam SIMILAR TO têm os mesmos riscos de segurança, porque SIMILAR TO oferece muitos recursos que são os mesmos oferecidos pelas expressões regulares no estilo POSIX.

As procuras que usam LIKE, como são muito mais simples que as outras duas opções, são mais seguras de serem usadas mesmo vindas de fontes possivelmente hostis.

As expressões regulares no estilo SIMILAR TO e POSIX não oferecem suporte para agrupamentos não determinísticos. Se for necessário, deve ser usado o LIKE ou aplicada uma ordenação diferente à expressão para contornar esta limitação.

9.7.1. LIKE #

string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]

A expressão LIKE retorna verdade se a string (cadeia de caracteres) corresponder ao pattern (padrão) fornecido. (Como esperado, a expressão NOT LIKE retorna falso se LIKE retornar verdade, e vice-versa. Uma expressão equivalente é NOT (string LIKE pattern).)

Se pattern não contiver sinais de porcentagem ou sublinhados, então o padrão representa apenas a própria cadeia de caracteres; Neste caso, LIKE funciona como o operador de igualdade. Um sublinhado (_) em pattern representa (corresponde a) qualquer um único caractere; o sinal de porcentagem (%) corresponde a qualquer sequência de zero ou mais caracteres.

Alguns exemplos:

'abc' LIKE 'abc'    → true
'abc' LIKE 'a%'     → true
'abc' LIKE '_b_'    → true
'abc' LIKE 'c'      → false

A correspondência de padrões LIKE oferece suporte a sequências de ordenação (collations) não determinísticas. (veja a Seção 23.2.2.4), tais como sequências de ordenação que não diferenciam letras maiúsculas de minúsculas ou sequências de ordenação que, por exemplo, ignoram a pontuação. Assim, com uma sequência de ordenação que não diferencia letras maiúsculas de minúsculas, seria possível ter:

'AbC' LIKE 'abc' COLLATE case_insensitive    → true
'AbC' LIKE 'a%' COLLATE case_insensitive     → true

Com sequências de ordenação que ignoram certos caracteres ou, em geral, que consideram cadeias de caracteres de comprimentos diferentes como iguais, a semântica pode se tornar um pouco mais complexa. Considere estes exemplos:

'.foo.' LIKE 'foo' COLLATE ign_punct    → true
'.foo.' LIKE 'f_o' COLLATE ign_punct    → true
'.foo.' LIKE '_oo' COLLATE ign_punct    → false

O funcionamento da correspondência consiste em particionar o padrão em sequências de caracteres curinga e sequências sem curinga (os curingas sendo _ e %). Por exemplo, o padrão f_o é particionado em f, _, o, o padrão _oo é particionado em _, oo. A cadeia de caracteres de entrada corresponde ao padrão se puder ser particionada de forma que os caracteres curinga correspondam a um caractere ou a qualquer número de caracteres, respectivamente, e as partições sem curinga sejam iguais sob a sequência de ordenação aplicável. Portanto, por exemplo, '.foo.' LIKE 'f_o' COLLATE ign_punct é verdade porque é possível particionar .foo. em .f, o, o. e então '.f' = 'f' COLLATE ign_punct, 'o' corresponde ao caractere curinga _, e 'o.' = 'o' COLLATE ign_punct. Mas '.foo.' LIKE '_oo' COLLATE ign_punct é falso porque .foo. não pode ser particionado de forma que o primeiro caractere seja qualquer caractere e o restante da cadeia de caracteres seja igual a oo. (Note que o caractere curinga de um único caractere sempre corresponde exatamente a um caractere, independentemente da sequência de ordenação. Portanto, neste exemplo _ corresponderia ao ., mas o restante da cadeia de caracteres de entrada não corresponderia ao restante do padrão.)

A correspondência de padrões LIKE sempre abrange toda a cadeia de caracteres. Portanto, se for desejado encontrar uma sequência em qualquer ponto de uma cadeia de caracteres, o padrão deve começar e terminar por um sinal de porcentagem.

Para corresponder a um caractere de sublinhado ou a um sinal de porcentagem sem corresponder a outros caracteres, o respectivo caractere em pattern deve ser precedido pelo caractere de escape. O caractere de escape padrão é a contrabarra, mas pode ser escolhido um caractere diferente usando a cláusula ESCAPE. Para corresponder ao próprio caractere de escape, devem ser escritos dois caracteres de escape.

Nota

Quando standard_conforming_strings está desligado (off), qualquer contrabarra que seja escrita em constantes de cadeia de caracteres precisa ser duplicada. Veja a Seção 4.1.2.1 para obter mais informações.

Também é possível selecionar nenhum caractere de escape escrevendo ESCAPE ''. Isto desativa efetivamente o mecanismo de escape, tornando impossível desativar o significado especial dos caracteres de sublinhado e porcentagem no padrão.

De acordo com o padrão SQL, omitir `ESCAPE` significa não haver caractere de escape (em vez de tornar a contrabarra o padrão), e um valor ESCAPE de comprimento zero não é permitido. O comportamento do PostgreSQL neste aspecto é, portanto, ligeiramente fora do padrão.

Pode ser usada a palavra-chave ILIKE em vez de LIKE para tornar a correspondência não sensível a letras maiúsculas e minúsculas, de acordo com a localidade ativa. (Mas isto não oferece suporte a sequências de ordenação não determinísticas.) Isto não está no padrão SQL, sendo uma extensão do PostgreSQL.

O operador ~~ é equivalente a LIKE, e ~~* corresponde a ILIKE. Também existem os operadores !~~ e !~~* que representam NOT LIKE e NOT ILIKE, respectivamente. Todos estes operadores são específicos do PostgreSQL. Podem ser encontrados estes nomes de operadores na saída do comando EXPLAIN e em locais semelhantes, uma vez que o analisador sintático traduz efetivamente LIKE e outros operadores para estes operadores.

As frases LIKE, ILIKE, NOT LIKE e NOT ILIKE são geralmente tratadas como operadores na sintaxe do PostgreSQL; por exemplo, podem ser usadas ​​em construções expressão operador ANY ( subconsulta), embora a cláusula ESCAPE não possa ser incluída neste caso. Em alguns casos obscuros, pode ser necessário usar os nomes dos operadores subjacentes.

Veja também o operador começa-por ^@ e a função starts_with() correspondente, que são úteis nos casos em que basta encontrar o início de uma cadeia de caracteres.

9.7.2. Expressões regulares SIMILAR TO #

string SIMILAR TO pattern [ESCAPE escape-character]
string NOT SIMILAR TO pattern [ESCAPE escape-character]

O operador SIMILAR TO retorna verdade ou falso dependendo se o padrão corresponde à cadeia de caracteres fornecida. É semelhante ao LIKE, exceto por interpretar o padrão usando a definição de expressão regular do SQL. As expressões regulares SQL são um cruzamento curioso entre a notação do LIKE e a notação de expressão regular comum (POSIX).

Como o LIKE, o operador SIMILAR TO é bem-sucedido apenas se o padrão corresponder a toda cadeia de caracteres; isto é diferente do comportamento comum de expressão regular, onde o padrão pode corresponder a qualquer parte da cadeia de caracteres. Também como o LIKE, SIMILAR TO usa _ e % como caracteres curinga denotando qualquer um único caractere e qualquer cadeia de caracteres, respectivamente (são comparáveis ao . e .* nas expressões regulares POSIX).

Além destas facilidades pegas emprestadas do LIKE, SIMILAR TO aceita estes meta caracteres de correspondência de padrões pegos emprestados das expressões regulares POSIX: [61]

  • | denota alternância (qualquer uma das duas alternativas).

  • * denota repetição do item anterior, zero ou mais vezes.

  • + denota repetição do item anterior, uma ou mais vezes.

  • ? denota repetição do item anterior, zero ou uma vez.

  • {m} denota repetição do item anterior, exatamente m vezes.

  • {m,} denota repetição do item anterior, m ou mais vezes.

  • {m,n} denota repetição do item anterior, pelo menos m e não mais que n vezes.

  • Podem ser usados parênteses () para agrupar itens em um único item lógico.

  • Uma expressão de colchetes [...] determina uma classe de caracteres, assim como nas expressões regulares POSIX.

Note que o ponto (.) não é um meta caractere para SIMILAR TO.

Assim como no LIKE, uma contrabarra desativa o significado especial de qualquer um desses meta caracteres. Pode ser especificado um caractere de escape diferente usando ESCAPE, ou a capacidade de escape pode ser desativada escrevendo ESCAPE ''.

De acordo com o padrão SQL, omitir `ESCAPE` significa não haver caractere de escape (em vez de tornar a contrabarra o padrão), e um valor ESCAPE de comprimento zero não é permitido. O comportamento do PostgreSQL neste aspecto é, portanto, ligeiramente fora do padrão.

Outra extensão fora do padrão é que o caractere de escape seguido por uma letra ou dígito fornece acesso às sequências de escape definidas para expressões regulares POSIX; veja a Tabela 9.20, a Tabela 9.21 e a Tabela 9.22 abaixo.

Alguns exemplos:

'abc' SIMILAR TO 'abc'          → true
'abc' SIMILAR TO 'a'            → false
'abc' SIMILAR TO '%(b|d)%'      → true
'abc' SIMILAR TO '(b|c)%'       → false
'-abc-' SIMILAR TO '%\mabc\M%'  → true
'xabcy' SIMILAR TO '%\mabc\M%'  → false

A função substring com três parâmetros permite a extração de uma sub-cadeia de caracteres que corresponde a um padrão de expressão regular SQL. A função pode ser escrita segundo a sintaxe SQL padrão:

substring(string similar pattern escape escape-character)

ou usando a agora obsoleta sintaxe do SQL:1999:

substring(string from pattern for escape-character)

ou como uma função comum de três argumentos:

substring(string, pattern, escape-character)

Assim como acontece com SIMILAR TO, o padrão especificado deve corresponder a toda cadeia de caracteres, caso contrário a função falha e retorna nulo. Para indicar a parte do padrão para a qual a sub-cadeia de caracteres correspondente é de interesse, o padrão deve conter duas ocorrências do caractere de escape seguido por aspas ("). O texto que corresponde à parte do padrão entre estes separadores é retornado quando a correspondência é bem-sucedida.

Na verdade, os separadores escape-aspas dividem o padrão da função substring em três expressões regulares independentes; por exemplo, uma barra vertical (|) em qualquer uma das três seções afeta apenas esta seção. Além disso, a primeira e a terceira destas expressões regulares são definidas para corresponder a menor quantidade possível de texto, não a maior, quando houver qualquer ambiguidade sobre o quanto da cadeia de caracteres corresponde a qual padrão. (Na linguagem POSIX, a primeira e a terceira expressões regulares são forçadas a não serem vorazes - non-greedy.)

Como extensão ao padrão SQL, o PostgreSQL permite a existência de apenas um separador escape-aspas, caso onde a terceira expressão regular é considerada vazia; ou nenhum separador, caso onde a primeira e a terceira expressões regulares são consideradas vazias.

Alguns exemplos com #" delimitando a cadeia de caracteres a ser retornada:

substring('foobar' similar '%#"o_b#"%' escape '#')   → oob
substring('foobar' similar '#"o_b#"%' escape '#')    → NULL

9.7.3. Expressões regulares POSIX #

A Tabela 9.16 lista os operadores disponíveis para correspondência de padrões usando expressões regulares POSIX [62].

Tabela 9.16. Operadores de correspondência de expressões regulares

Operador

Descrição

Exemplo(s)

text ~ textboolean

A cadeia de caracteres corresponde à expressão regular; diferencia letras maiúsculas de minúsculas

'thomas' ~ 't.*ma't

text ~* textboolean

A cadeia de caracteres corresponde à expressão regular; não diferencia letras maiúsculas de minúsculas

'thomas' ~* 'T.*ma't

text !~ textboolean

A cadeia de caracteres não corresponde à expressão regular; diferencia letras maiúsculas de minúsculas

'thomas' !~ 't.*max't

text !~* textboolean

A cadeia de caracteres não corresponde à expressão regular; não diferencia letras maiúsculas de minúsculas

'thomas' !~* 'T.*ma'f


As expressões regulares POSIX fornecem um meio mais poderoso para correspondência de padrões que os operadores LIKE e SIMILAR TO. Muitas ferramentas Unix, como egrep, sed e awk usam uma linguagem de correspondência de padrões semelhante à descrita aqui.

Uma expressão regular é uma sequência de caracteres que é uma definição abreviada de um conjunto de caracteres (um conjunto regular). Diz-se que uma cadeia de caracteres corresponde a uma expressão regular, se for membro do conjunto regular descrito pela expressão regular. Assim como no LIKE, os caracteres do padrão correspondem exatamente aos caracteres da cadeia de caracteres, a menos que sejam caracteres especiais na linguagem de expressão regular — porém, expressões regulares usam caracteres especiais diferentes do LIKE. Ao contrário dos padrões do LIKE, uma expressão regular pode corresponder a qualquer lugar dentro da cadeia de caracteres, a menos que a expressão regular seja explicitamente ancorada no início ou no fim da cadeia de caracteres.

Alguns exemplos:

'abcd' ~ 'bc'     → true
'abcd' ~ 'a.c'    → true  — o ponto corresponde a qualquer caractere
'abcd' ~ 'a.*d'   → true  * repete o elemento de padrão anterior
'abcd' ~ '(b|x)'  → true  | significa OR, para o grupo entre parênteses
'abcd' ~ '^a'     → true  ^ ancora no início da cadeia de caracteres
'abcd' ~ '^(b|c)' → false — coresponderia, exceto pela ancoragem

A linguagem de padrões POSIX está descrita com muito mais detalhes abaixo. [63]

A função substring com dois parâmetros, substring(string from pattern), permite a extração de uma sub-cadeia de caracteres que corresponde a um padrão de expressão regular POSIX. A função retorna nulo caso não haja correspondência, caso contrário retorna a primeira parte do texto que corresponde ao padrão. Mas se o padrão contiver parênteses, retorna a parte do texto que corresponde à primeira subexpressão entre parênteses (aquela cujo parêntese esquerdo vem primeiro). Podem ser colocados parênteses ao redor de toda a expressão, se for desejado usar parênteses dentro da expressão sem acionar esta exceção. Se for necessário usar parênteses no padrão antes da subexpressão que se deseja extrair, então consulte os parênteses sem captura descritos abaixo.

Alguns exemplos:

substring('foobar' from 'o.b')     → oob
substring('foobar' from 'o(.)b')   → o

A função regexp_count conta o número de ocorrências de uma expressão regular POSIX em uma cadeia de caracteres. Possui a sintaxe regexp_count(string, pattern [, start [, flags ]]). pattern é procurado na string, normalmente a partir do início da cadeia de caracteres, mas se for fornecido o parâmetro start, então irá começar a partir deste índice de caractere. O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. Por exemplo, incluir i em flags especifica a correspondência que não diferencia letras maiúsculas de minúsculas. Os sinalizadores aceitos estão descritos na Tabela 9.24.

Alguns exemplos:

regexp_count('ABCABCAXYaxy', 'A.')          → 3
regexp_count('ABCABCAXYaxy', 'A.', 1, 'i')  → 4

A função regexp_instr retorna a posição inicial ou final da N-ésima correspondência de um padrão de expressão regular POSIX em uma cadeia de caracteres, ou zero se não houver tal correspondência. Possui a sintaxe regexp_instr(string, pattern [, start [, N [, endoption [, flags [, subexpr ]]]]]). pattern é procurado na string, normalmente a partir do início da cadeia de caracteres, mas se for fornecido o parâmetro start, então irá começar a partir deste índice de caractere. Se for especificado N será localizada a N-ésima correspondência do padrão, caso contrário será localizada a primeira correspondência. Se o parâmetro endoption for omitido ou especificado como zero, a função irá retornar a posição do primeiro caractere da correspondência. Caso contrário, endoption deverá ser um, e a função irá retornar a posição do caractere seguinte à correspondência. O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. Os sinalizadores aceitos estão descritos na Tabela 9.24. Para um padrão que contenha subexpressões entre parênteses, subexpr é um número inteiro que indica qual subexpressão é de interesse: o resultado identifica a posição da sub-cadeia de caracteres que corresponde àquela subexpressão. As subexpressões são numeradas na ordem dos parênteses iniciais. Quando subexpr é omitido ou é zero, o resultado identifica a posição de toda a correspondência, independentemente das subexpressões entre parênteses.

Alguns exemplos:

regexp_instr('number of your street, town zip, FR',
             '[^,]+', 1, 2)
    → 23
regexp_instr(string=>'ABCDEFGHI',
             pattern=>'(c..)(...)',
             start=>1, "N"=>1,
             endoption=>0,
             flags=>'i',
             subexpr=>2)
    → 6

A função regexp_like verifica se ocorre alguma correspondência com um padrão de expressão regular POSIX em uma cadeia de caracteres, retornando um valor booleano verdade ou falso. Possui a sintaxe regexp_like(string, pattern [, flags ]). O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. Os sinalizadores aceitos estão descritos na Tabela 9.24. Esta função irá produzir os mesmos resultados que o operador ~ se não for especificado nenhum sinalizador. Se for especificado apenas o sinalizador i, esta função irá produzir os mesmos resultados que o operador ~*.

Alguns exemplos:

regexp_like('Hello World', 'world')       → false
regexp_like('Hello World', 'world', 'i')  → true

A função regexp_match retorna uma matriz de texto contendo as sub-cadeias de caracteres capturadas, resultantes da primeira correspondência entre um padrão de expressão regular POSIX e uma cadeia de caracteres. Possui a sintaxe regexp_match(string, pattern [, flags ]). Se não houver correspondência, o resultado será NULL. Se for encontrada uma correspondência e o pattern não contiver subexpressões entre parênteses, o resultado será uma matriz de texto de elemento único contendo a sub-cadeia de caracteres que corresponde a todo o padrão. Se for encontrada uma correspondência e o pattern contiver subexpressões entre parênteses, o resultado será uma matriz de texto cujo n-ésimo elemento será a sub-cadeia de caracteres que corresponde à n-ésima subexpressão entre parênteses de pattern (sem contar os parênteses não capturáveis; veja os detalhes abaixo). O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. Os sinalizadores com suporte (exceto o g) estão descritos na Tabela 9.24.

Alguns exemplos:

SELECT regexp_match('foobarbequebaz', 'bar.*que');

 regexp_match
--------------
 {barbeque}
(1 linha)

SELECT regexp_match('foobarbequebaz', '(bar)(beque)');

 regexp_match
--------------
 {bar,beque}
(1 linha)

Dica

No caso comum em que se deseja apenas a sub-cadeia de caracteres correspondente inteira ou NULL para nenhuma correspondência, a melhor solução é usar a função regexp_substr(). Entretanto, regexp_substr() somente existe nas versões 15 e superiores do PostgreSQL. Ao trabalhar com versões mais antigas, pode ser extraído o primeiro elemento do resultado de regexp_match() como, por exemplo:

SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];

 regexp_match
--------------
 barbeque
(1 linha)

A função regexp_matches retorna um conjunto de matrizes de texto contendo as sub-cadeias de caracteres capturadas resultantes da correspondência do padrão da expressão regular POSIX com a cadeia de caracteres. Possui a mesma sintaxe da função regexp_match. Esta função não retorna nenhuma linha caso não haja correspondência, retorna uma linha se houver correspondência e o sinalizador g não for especificado, ou retorna N linhas se houver N correspondências e o sinalizador g for especificado. Cada linha retornada é uma matriz de texto contendo toda a sub-cadeia de caracteres que corresponde ao padrão, ou as sub-cadeias de caracteres que correspondem às subexpressões entre parênteses do pattern, exatamente como descrito acima para a função regexp_match. A função regexp_matches aceita todos os sinalizadores descritos na Tabela 9.24, mais o sinalizador g, que a sinaliza o retorno de todas as correspondências, e não apenas a primeira.

Alguns exemplos:

SELECT regexp_matches('foo', 'not there');

 regexp_matches
----------------
(0 linha)

SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');

 regexp_matches
----------------
 {bar,beque}
 {bazil,barf}
(2 linhas)

Dica

Geralmente, a função regexp_matches() deve ser usada com o sinalizador g, porque se for desejado apenas a primeira correspondência, é mais fácil e eficiente usar a função regexp_match(). Entretanto, regexp_match() existe apenas no PostgreSQL versão 10 e superior. Ao se trabalhar em versões mais antigas, um truque comum é colocar uma chamada à função regexp_matches() em uma subseleção; por exemplo:

SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;

Isto produz uma matriz de texto quando há uma correspondência, ou NULL quando não há, idêntico ao que função regexp_match() faria. Sem a subseleção, esta consulta não produziria nenhuma saída para as linhas da tabela sem uma correspondência, o que normalmente não é o comportamento desejado.

A função regexp_replace fornece a substituição por um novo texto para sub-cadeias de caracteres que correspondem a padrões de expressão regular POSIX. Possui a sintaxe regexp_replace(string, pattern, replacement [, flags ]) ou regexp_replace(string, pattern, replacement, start [, N [, flags ]]). A cadeia de caracteres de origem (string) é retornada sem alterações quando não há correspondência com o padrão (pattern). Caso haja uma correspondência, a cadeia de caracteres string será retornada com a cadeia de caracteres replacement substituída pela sub-cadeia de caracteres correspondente. A cadeia de caracteres replacement pode conter \n, onde n varia de 1 a 9, para indicar que a sub-cadeia de caracteres de origem que corresponde a n-ésima subexpressão entre parênteses do padrão deve ser inserida, e pode conter \& para indicar que deve ser inserida a sub-cadeia de caracteres que corresponde a todo o padrão. Deve ser escrito \\ se for necessário inserir uma contrabarra no no texto de substituição. pattern é procurado na string, normalmente a partir do início da cadeia de caracteres, mas se for fornecido o parâmetro start, então irá começar a partir deste índice de caractere. Por padrão, apenas a primeira correspondência do padrão é substituída. Se N for especificado e for maior que zero, então será substituída a N-ésima correspondência do padrão. Se o sinalizador g for fornecido, ou se N for especificado e for zero, todas as correspondências na posição start ou após ela serão substituídas. (O sinalizador g é ignorado quando N é especificado.) O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. Os sinalizadores aceitos (exceto o g) estão descritos na Tabela 9.24.

Alguns exemplos:

regexp_replace('foobarbaz', 'b..', 'X')
    → fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
    → fooXX
regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
    → fooXarYXazY
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i')
    → X PXstgrXSQL fXnctXXn
regexp_replace(string=>'A PostgreSQL function',
               pattern=>'a|e|i|o|u',
               replacement=>'X',
               start=>1,
               "N"=>3,
               flags=>'i')
    → A PostgrXSQL function

A função regexp_split_to_table divide uma cadeia de caracteres usando um padrão de expressão regular POSIX como delimitador. Possui a sintaxe regexp_split_to_table( string, pattern [, flags ]). Se não houver correspondência com o pattern, a função retorna a string. Se houver pelo menos uma correspondência, para cada correspondência a função retorna o texto do final da última correspondência (ou do início da cadeia de caracteres) até o início da correspondência. Quando não há mais correspondências, a função retorna o texto do final da última correspondência até o final da cadeia de caracteres. O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. A função regexp_split_to_table aceita os sinalizadores descritos na Tabela 9.24.

A função regexp_split_to_array se comporta da mesma maneira que a função regexp_split_to_table, exceto pela função regexp_split_to_array retornar seus resultados como uma matriz de text. Possui a sintaxe regexp_split_to_array( string, pattern [, flags ]). Os parâmetros são os mesmos da função regexp_split_to_table.

Alguns exemplos:

SELECT foo
    FROM regexp_split_to_table(
             'the quick brown fox jumps over the lazy dog',
             '\s+') AS foo;

  foo
-------
 the
 quick
 brown
 fox
 jumps
 over
 the
 lazy
 dog
(9 linhas)

SELECT regexp_split_to_array(
             'the quick brown fox jumps over the lazy dog',
             '\s+');

             regexp_split_to_array
-----------------------------------------------
 {the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 linha)

SELECT foo
    FROM regexp_split_to_table(
             'the quick brown fox',
             '\s*') AS foo;

 foo
-----
 t
 h
 e
 q
 u
 i
 c
 k
 b
 r
 o
 w
 n
 f
 o
 x
(16 linhas)

Como o último exemplo demonstra, as funções de divisão de expressões regulares ignoram correspondências de comprimento zero que ocorrem no início ou no final da cadeia de caracteres ou imediatamente após uma correspondência anterior. Isto contraria a definição estrita de correspondência de expressões regulares implementada pelas outras funções de expressões regulares, mas geralmente é o comportamento mais conveniente na prática. Outros sistemas de software, como o Perl, usam definições semelhantes.

A função regexp_substr retorna a sub-cadeia de caracteres que corresponde a um padrão de expressão regular POSIX, ou NULL se não houver correspondência. Possui a sintaxe regexp_substr(string, pattern [, start [, N [, flags [, subexpr ]]]]). pattern é procurado na string, normalmente a partir do início da cadeia de caracteres, mas se for fornecido o parâmetro start, então irá começar a partir deste índice de caractere. Se N for especificado, então será retornada a N-ésima correspondência do padrão, caso contrário, será retornada a primeira correspondência. O parâmetro flags é uma cadeia de caracteres de texto opcional contendo zero ou mais sinalizadores de uma única letra que alteram o comportamento da função. Os sinalizadores aceitos (exceto o g) estão descritos na Tabela 9.24. Para um padrão que contenha subexpressões entre parênteses, subexpr é um número inteiro indicando qual subexpressão é de interesse: o resultado é a sub-cadeia de caracteres que corresponde àquela subexpressão. As subexpressões são numeradas na ordem dos parênteses iniciais. Quando subexpr é omitido ou zero, o resultado é a correspondência completa, independentemente das subexpressões entre parênteses.

Alguns exemplos:

regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2)
    → town zip
regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
    → FGH

9.7.3.1. Detalhes sobre expressões regulares #

As expressões regulares do PostgreSQL são implementadas usando um pacote de software escrito por Henry Spencer. Grande parte da descrição das expressões regulares abaixo foi copiada literalmente de seu manual.

As expressões regulares (REs), conforme definidas no POSIX 1003.2, vêm em duas formas: as REs estendidas, ou EREs (aproximadamente as do egrep), e as REs básicas, ou BREs (aproximadamente as do ed). O PostgreSQL oferece suporte às duas formas, e também implementa algumas extensões que não estão no padrão POSIX, mas se tornaram amplamente utilizadas devido à sua disponibilidade em linguagens de programação como Perl e Tcl. As REs que usam as extensões não-POSIX são chamadas de REs avançadas, ou AREs nesta documentação. AREs são quase um superconjunto exato de EREs, mas as BREs têm várias incompatibilidades de notação (além de serem muito mais limitadas). Primeiro descrevemos as formas ARE e ERE, observando os recursos que se aplicam apenas às AREs e, em seguida, descrevemos como as BREs diferem.

Nota

O PostgreSQL sempre presume inicialmente que uma expressão regular segue as regras das ARE. Entretanto, as regras mais limitadas das ERE ou BRE podem ser escolhidas adicionando uma opção incorporada ao padrão RE, conforme descrito na Seção 9.7.3.4. Pode ser útil para manter a compatibilidade com aplicações que esperam exatamente as regras do POSIX 1003.2.

Uma expressão regular é definida como uma ou mais ramificações separadas por |. Ela corresponde a qualquer coisa que corresponda a um dos ramos.

Uma ramificação é constituída por zero ou mais átomos quantificados, ou restrições, concatenados. Ela corresponde a uma correspondência para o primeiro, seguida por uma correspondência para o segundo, etc.; uma ramificação vazia corresponde à cadeia de caracteres vazia.

Um átomo quantificado é um átomo possivelmente seguido por um único quantificador. Sem o quantificador, corresponde a uma correspondência para o átomo. Com o quantificador, pode corresponder a um certo número de correspondências do átomo. Um átomo pode ser qualquer uma das possibilidades descritas na Tabela 9.17. Os quantificadores possíveis e seus significados são descritos na Tabela 9.18.

Uma restrição corresponde a uma cadeia de caracteres vazia, mas corresponde apenas quando são atendidas condições específicas. Uma restrição pode ser usada onde um átomo pode ser usado, exceto que não pode ser seguida por um quantificador. As restrições simples estão descritas na Tabela 9.19; algumas outras restrições são descritas posteriormente.

Tabela 9.17. Átomos de expressões regulares

ÁtomoDescrição
(re) (onde re é qualquer expressão regular) corresponde a uma correspondência para re, com a correspondência registrada para possível captura
(?:re) como acima, mas a correspondência não é registrada para captura (um conjunto de parênteses não-capturantes) (somente nas ARE)
. corresponde a qualquer um único caractere
[caracteres] uma expressão de colchetes, correspondendo a qualquer um dos caracteres (veja a Seção 9.7.3.2 para obter mais detalhes)
\k (onde k é um caractere não alfanumérico) corresponde a esse caractere tomado como um caractere comum; por exemplo, \\ corresponde ao caractere de contrabarra
\c onde c é alfanumérico (possivelmente seguido por outros caracteres) é um escape, veja a Seção 9.7.3.3 (somente nas AREs; nas EREs e BREs, isto corresponde a c)
{ quando seguido por um caractere diferente de um dígito, corresponde ao caractere chave esquerda {; quando seguido por um dígito, é o início de um limite (veja abaixo)
x onde x é um único caractere sem outro significado, corresponde a esse caractere

Uma RE não pode terminar por contrabarra (\).

Nota

Se o parâmetro de configuração standard_conforming_strings estiver desligado (off), quaisquer contrabarras escritas em literais cadeia de caracteres precisam ser duplicadas. Veja Seção 4.1.2.1 para obter mais informações.

Tabela 9.18. Quantificadores de expressões regulares

QuantificadorCorrespondência
* uma sequência de 0 ou mais correspondências do átomo
+ uma sequência de 1 ou mais correspondências do átomo
? uma sequência de 0 ou 1 correspondências do átomo
{m} uma sequência de exatamente m correspondências do átomo
{m,} uma sequência de m ou mais correspondências do átomo
{m,n} uma sequência de m até n (inclusive) correspondências do átomo; m não pode ser maior que n
*? a versão não voraz de *
+? a versão não voraz de +
?? a versão não voraz de ?
{m}? a versão não voraz de {m}
{m,}? a versão não voraz de {m,}
{m,n}? a versão não voraz de {m,n}

As formas que usam {...} são conhecidas como limites. Os números m e n em um limite são números inteiros decimais sem sinal com valores permitidos de 0 a 255, inclusive.

Os quantificadores não-vorazes (disponíveis apenas nas AREs) correspondem às mesmas possibilidades que seus correspondentes normais (vorazes), mas preferem o menor número, em vez do maior número, de correspondências. Veja a Seção 9.7.3.5 para obter mais detalhes.

Nota

Um quantificador não pode vir logo após outro quantificador; por exemplo, ** não é válido. Um quantificador não pode iniciar uma expressão ou subexpressão, ou seguir ^ ou |.

Tabela 9.19. Restrições de expressões regulares

RestriçãoDescrição
^ corresponde no início da cadeia de caracteres
$ corresponde ao final da cadeia de caracteres
(?=re) avanço positivo corresponde a qualquer ponto onde uma sub-cadeia de caracteres que corresponda a re inicia (somente nas ARE)
(?!re) avanço negativo corresponde em qualquer ponto onde nenhuma sub-cadeia de caracteres que corresponda a re inicie (somente nas ARE)
(?<=re) recuo positivo corresponde a qualquer ponto onde uma sub-cadeia de caracteres que corresponda a re termina (somente nas ARE)
(?<!re) recuo negativo corresponde em qualquer ponto onde nenhuma sub-cadeia de caracteres que corresponda a re termine (somente nas ARE)

As restrições de avanço e recuo (lookahead/lookbehind) não podem conter referências inversas [64] [65] (veja a Seção 9.7.3.3), e todos os parênteses dentro delas são considerados não-capturantes.

9.7.3.2. Expressões de colchetes #

Uma expressão de colchetes é uma lista de caracteres entre []. Normalmente corresponde a qualquer caractere da lista (mas veja abaixo). Se a lista começar com ^, então corresponde a qualquer caractere que não esteja na lista [66]. Se dois caracteres na lista estiverem separados por hífen (-), este é um atalho para o intervalo completo de caracteres entre estes dois (inclusive) na sequência de ordenação (collating); por exemplo, [0-9] em ASCII corresponde a qualquer dígito decimal. Não é permitido que dois intervalos compartilhem um ponto de extremidade; por exemplo, a-c-e. Os intervalos são muito dependentes da sequência de ordenação, portanto os programas com portabilidade devem evitar depender deles.

Para incluir o caractere literal ] na lista, torne-o o primeiro caractere da lista (após o ^, se este for usado). Para incluir o caractere literal - na lista, torne-o o primeiro ou o último caractere da lista, ou o segundo ponto final de um intervalo. Para usar o caractere literal - como o primeiro ponto final de um intervalo, coloque-o entre [. e .] para torná-lo um elemento de ordenação (veja abaixo). Com exceção desses caracteres, certas combinações usando [ (veja os próximos parágrafos) e escapes (somente nas ARE), todos os outros caracteres especiais perdem seu significado especial em uma expressão de colchetes. Em particular, \ não é especial quando se segue as regras ERE ou BRE, embora seja especial (como introduzir um escape) nas ARE.

Dentro de uma expressão de colchetes, um elemento de ordenação (um caractere, uma sequência de vários caracteres que ordenam como se fosse um único caractere, ou um nome de sequência de ordenação) entre [. e .], representa a sequência de caracteres desse elemento de ordenação. A sequência é tratada como sendo um único elemento da lista da expressão de colchetes. Isto permite que uma expressão de colchetes contendo um elemento de ordenação de vários caracteres corresponda a mais de um caractere; por exemplo, se a sequência de ordenação incluir o elemento de ordenação ch, então a expressão regular [[.ch.]]*c corresponderá aos primeiros cinco caracteres de chchcc.

Nota

No momento, o PostgreSQL não oferece suporte a elementos de ordenação de vários caracteres. Esta informação descreve um possível comportamento futuro.

Dentro de uma expressão de colchetes, um elemento de ordenação entre [= e =] é uma classe de equivalência, representando as sequências de caracteres de todos os elementos de ordenação equivalentes a esta classe, incluindo ela mesma. (Se não houver outros elementos de ordenação equivalentes, o tratamento é como se os delimitadores que circundam fossem [. e .].) Por exemplo, se o e ^ são membros de uma classe de equivalência, então [[=o=]], [[=^=]] e [o^] são todos sinônimos. Uma classe de equivalência não pode ser um ponto final de um intervalo.

Dentro de uma expressão de colchetes, o nome de uma classe de caracteres entre [: e :] representa a lista de todos os caracteres pertencentes a esta classe. Uma classe de caracteres não pode ser usada como ponto final de um intervalo. O padrão POSIX define estes nomes de classes de caracteres: alnum (letras e dígitos numéricos), alpha (letras), blank (espaço e tabulação), cntrl (caracteres de controle), digit (numeric digits), graph (caracteres imprimíveis, exceto espaço), lower (letras minúsculas), print (caracteres imprimíveis, incluindo espaço), punct (pontuação), space (qualquer espaço em branco), upper (letras maiúsculas) e xdigit (dígitos hexadecimais). O comportamento destas classes de caracteres padrão geralmente é consistente em todas as plataformas para caracteres no conjunto ASCII de 7 bits. Se um determinado caractere não ASCII é considerado pertencente a uma destas classes depende da ordenação (collation) usada para a função ou operador de expressão regular (veja a Seção 23.2), ou por padrão a configuração de localidade LC_CTYPE do banco de dados (veja a Seção 23.1). A classificação [67] de caracteres não ASCII pode variar entre plataformas, mesmo em localidades com nomes semelhantes. (Mas a localidade C nunca considera um caractere não-ASCII como pertencente a uma destas classes.) Além destas classes de caracteres padrão, o PostgreSQL define a classe de caracteres word, que é idêntica à classe de caracteres alnum, acrescida do caractere sublinhado (_) e da classe de caractere ascii, que contém exatamente o conjunto ASCII de 7 bits.

Existem dois casos especiais de expressões de colchetes: as expressões de colchetes [[:<:]] e [[:>:]] são restrições, combinando com cadeias de caracteres vazias no início e no fim da palavra, respectivamente. Uma palavra é definida como uma sequência de caracteres de palavra, que não é precedida nem seguida por caracteres de palavra. Um caractere de palavra é qualquer caractere pertencente à classe de caracteres word, ou seja, qualquer letra, dígito ou sublinhado. Esta é uma extensão, compatível com, mas não especificada pelo POSIX 1003.2, e deve ser usada com cautela em software destinado a ser portável para outros sistemas. Os escapes de restrição descritos abaixo são geralmente preferíveis; não são mais padrão, mas são mais fáceis de digitar.

9.7.3.3. Escapes de expressões regulares #

Escapes são sequências especiais começando com \seguido de um caractere alfanumérico. Escapes vêm em várias variedades: entrada de caracteres, atalhos de classe, escapes de restrição e referências inversas. Uma \ seguida por um caractere alfanumérico, mas não constituindo um escape válido é ilegal nas ARE. Nas ERE, não há escapes: fora de uma expressão de colchetes, uma \ seguida por um caractere alfanumérico representa apenas esse caractere como um caractere comum e, em uma expressão de colchetes, \ é um caractere comum. (Esse último é a única incompatibilidade real entre as ERE e as ARE.)

Os escapes de entrada de caractere existem para facilitar a especificação de caracteres não imprimíveis e outros caracteres inconvenientes nas RE. Estão descritos na Tabela 9.20.

Os escapes de atalho de classe fornecem atalhos para certas classes de caracteres comumente usadas. Estão descritos na Tabela 9.21.

O escape de restrição é uma restrição, que corresponde à cadeia de caracteres vazia, se forem atendidas condições específicas, escrita como um escape. Estão descritos na Tabela 9.22.

Uma referência inversa (\n) corresponde à mesma cadeia de caracteres correspondida pela subexpressão anterior entre parênteses especificada pelo número n (veja a Tabela 9.23). Por exemplo, ([bc])\1 corresponde a bb ou cc, ma não a bc ou cb. A subexpressão deve preceder inteiramente a referência inversa na RE. As subexpressões são numeradas na ordem de seus parênteses iniciais. Parênteses não-capturantes não definem subexpressões. A referência inversa considera apenas os caracteres de cadeia de caracteres que correspondem à subexpressão referenciada, não quaisquer restrições contidas nela. Por exemplo, (^\d)\1 corresponde com 22.

Tabela 9.20. Escapes de entrada de caractere de expressão regular

EscapeDescrição
\a caractere de alerta (campainha), como na linguagem C
\b retrocesso, como na linguagem C
\B sinônimo de contrabarra (\) , para ajudar a reduzir a necessidade de dobrar a contrabarra
\cX (onde X é qualquer caractere) o caractere cujos 5 bits de ordem inferior são os mesmos que os de X, e cujos demais bits são todos zero
\e o caractere cujo nome de sequência de ordenação é ESC, ou se isto falhar, o caractere com valor octal 033
\f avanço de formulário, como na linguagem C
\n nova linha, como na linguagem C
\r retorno de carro, como na linguagem C
\t tabulação horizontal, como na linguagem C
\uwxyz (onde wxyz são exatamente quatro dígitos hexadecimais) o caractere cujo valor hexadecimal é 0xwxyz
\Ustuvwxyz (onde stuvwxyz são exatamente oito dígitos hexadecimais) o caractere cujo valor hexadecimal é 0xstuvwxyz
\v tabulação vertical, como na linguagem C
\xhhh (onde hhh é qualquer sequência de dígitos hexadecimais) o caractere cujo valor hexadecimal é 0xhhh (um único caractere, não importando quantos dígitos hexadecimais sejam usados)
\0 o caractere cujo valor é 0 (o byte nulo)
\xy (onde xy são exatamente dois dígitos octais, e não é uma referência inversa) o caractere cujo valor octal é 0xy
\xyz (onde xyz são exatamente três dígitos octais e não é uma referência inversa) o caractere cujo valor octal é 0xyz

Os dígitos hexadecimais são 0-9, a-f e A-F. Os dígitos octais são 0-7.

Os escapes de entrada de caracteres numéricos, especificando valores fora do intervalo ASCII (0–127), têm significados dependentes da codificação do banco de dados. Quando a codificação é UTF-8, os valores de escape são equivalentes aos pontos de código Unicode; por exemplo, \u1234 significa o caractere U+1234. Para outras codificações multibyte, escapes de entrada de caractere geralmente especificam apenas a concatenação dos valores de byte para o caractere. Se o valor de escape não corresponder a algum caractere válido na codificação do banco de dados, nenhum erro será gerado, mas nunca corresponderá a nenhum dado.

Os escapes de entrada de caractere são sempre considerados caracteres comuns. Por exemplo, \135 é ] in ASCII, mas \135 não termina uma expressão de colchetes.

Tabela 9.21. Escapes atalho de classe de expressão regular

EscapeDescrição [a]
\d corresponde a qualquer caractere que seja um dígito, como [[:digit:]]
\s corresponde a qualquer caractere que seja de espaço em branco, como [[:space:]]
\w corresponde a qualquer caractere de palavra, como [[:word:]]
\D corresponde a qualquer caractere que não seja um dígito, como [^[:digit:]]
\S corresponde a qualquer caractere que não seja de espaço em branco, como [^[:space:]]
\W corresponde a qualquer caractere que não seja um caractere de palavra, como [^[:word:]]

Exemplo 9.1. Exemplo do tradutor

Primeira sub-cadeia de caracteres que corresponde ao padrão.

SELECT regexp_substr('!@#123_xyz$%456', '[[:word:]]+');

 regexp_substr
---------------
 123_xyz
(1 linha)

SELECT regexp_substr('!@#123_xyz$%456', '[[:alpha:]]+');

 regexp_substr
---------------
 xyz
(1 linha)

Obs: sem o sinal de + no padrão só é retornado o primeiro caractere da correspondência.


Os escapes atalho de classe também funcionam dentro de expressões de colchetes, embora as definições descritas acima não sejam sintaticamente válidas neste contexto. Por exemplo, [a-c\d] equivale a [a-c[:digit:]].

Tabela 9.22. Escapes de restrição de expressão regular

EscapeDescrição
\A corresponde apenas no início da cadeia de caracteres (veja na Seção 9.7.3.5 como isto difere de ^)
\m corresponde apenas no início da palavra
\M corresponde apenas no final da palavra
\y corresponde apenas no início ou no final da palavra
\Y corresponde apenas em um ponto que não está nem no início nem no fim da palavra
\Z corresponde apenas no final da cadeia de caracteres (veja na Seção 9.7.3.5 como isto difere de $)

Uma palavra é definida como na especificação de [[:<:]] e [[:>:]] acima. Escapes de restrição são ilegais dentro de expressões de colchetes.

Tabela 9.23. Referências invertidas de expressão regular

EscapeDescrição
\m (onde m é um dígito diferente de zero) uma referência invertida para a m-ésima subexpressão
\mnn (onde m é um dígito diferente de zero, e nn são alguns dígitos a mais, e o valor decimal mnn não é maior que o número de parênteses de fechamento de captura vistos até agora) uma referência invertida para a mnn-ésima subexpressão

Nota

Há uma ambiguidade inerente entre escapes de entrada de caracteres octais e referências inversas, resolvida pelas heurísticas a seguir, conforme sugerido acima. Um zero inicial sempre indica um escape octal. Um único dígito diferente de zero, não seguido por outro dígito, é sempre tomado como referência inversa. Uma sequência de vários dígitos que não comece com zero é considerada uma referência inversa se vier após uma subexpressão adequada (ou seja, o número está no intervalo legal para uma referência inversa), caso contrário é tomado como octal.

9.7.3.4. Metassintaxe de expressões regulares #

Além da sintaxe principal descrita acima, existem algumas formas especiais e diversas facilidades sintáticas disponíveis.

Uma RE pode iniciar por um dos dois prefixos diretor especiais. Se uma RE começa com ***:, o restante da RE é tomada como uma ARE. (Isto normalmente não tem efeito no PostgreSQL, uma vez que as RE são assumidas como sendo ARE; mas tem efeito se o modo ERE ou BRE tiver sido especificado pelo parâmetro sinalizadores para uma função de expressão regular.) Se uma RE começa com ***=, o restante da RE é considerado um literal cadeia de caracteres, com todos os caracteres considerados como caracteres comuns.

Uma ARE pode começar com opções incorporadas: a sequência (?xyz) (onde xyz é um ou mais caracteres alfabéticos) determina opções que afetam o resto da RE. Estas opções substituem quaisquer opções previamente determinadas — em particular, podem substituir o comportamento de diferenciação entre letras maiúsculas e minúsculas implícito por um operador de expressão regular, ou o parâmetro sinalizadores de uma função de expressão regular. As letras de opção disponíveis estão descritas na Tabela 9.24. Note que estas mesmas letras de opção são usadas nos parâmetros sinalizadores das funções de expressão regular.

Tabela 9.24. Letras de opção incorporada das ARE

OpçãoDescrição
b o restante da RE é uma BRE
c correspondência com distinção entre letras maiúsculas e minúsculas (substitui o tipo de operador)
e o restante da RE é uma ERE
i correspondência sem distinção entre letras maiúsculas e minúsculas (veja a Seção 9.7.3.5) (substitui o tipo de operador)
m sinônimo histórico para n
n correspondência sensível a nova linha (veja a Seção 9.7.3.5)
p correspondência parcial sensível à nova linha (veja a Seção 9.7.3.5)
q o restante da RE é uma cadeia de caracteres literal (entre aspas), com todos os caracteres comuns
s correspondência não sensível a nova linha (o padrão)
t sintaxe justa (o padrão; veja abaixo)
w correspondência parcial inversa sensível a nova linha (esquisita) (veja a Seção 9.7.3.5)
x sintaxe expandida (veja abaixo)

As opções incorporadas têm efeito no ) que termina a sequência. Eles podem aparecer apenas no início de uma ARE (após a diretor ***:, se houver algum).

Além da sintaxe RE usual (justa), onde todos os caracteres são significativos, existe a sintaxe expandida, disponível especificando a opção incorporada x. Na sintaxe expandida, os caracteres de espaço em branco na RE são ignorados, assim como todos os caracteres entre o # e a próxima nova linha (ou o final do RE). Isto permite criar parágrafos e comentar uma RE complexa. Existem três exceções a esta regra básica:

  • um caractere de espaço em branco ou # precedido por \ é mantido

  • espaço em branco ou # em uma expressão de colchetes é mantido

  • espaço em branco e comentários não podem aparecer em símbolos multi-caracteres, como (?:

Para esta finalidade, os caracteres de espaço em branco são: branco, tabulação, nova linha, e qualquer caractere que pertença à classe de caracteres space.

Finalmente, em uma expressão ARE, fora dos colchetes, a sequência (?#ttt) (onde ttt é qualquer texto que não contenha um )) é um comentário, inteiramente ignorado. Novamente, isto não é permitido entre os caracteres de símbolos multi-caracteres, como (?:. Esses comentários são mais uma peça histórica do que um recurso útil, e seu uso está obsoleto; deve-se usar a sintaxe expandida em seu lugar.

Nenhuma destas extensões de meta sintaxe está disponível se um diretor ***= inicial tiver especificado que a entrada do usuário seja tratada como um literal cadeia de caracteres em vez de uma RE.

9.7.3.5. Regras de correspondência de expressões regulares #

No caso da RE corresponder a mais de uma sub-cadeia de caracteres de uma determinada cadeia de caracteres, a RE corresponde à que começa mais cedo na cadeia de caracteres. Se a RE puder corresponder a mais de uma sub-cadeia de caracteres a partir desse ponto, a correspondência mais longa possível ou a correspondência mais curta possível será usada, dependendo se a RE é voraz (greedy) ou não-voraz (non-greedy).

Se uma RE é voraz ou não é determinado pelas seguintes regras:

  • A maioria dos átomos e todas as restrições não possuem atributo de voracidade (porque não podem corresponder a quantidades variáveis de texto de qualquer maneira).

  • Adicionar parênteses em torno da RE não altera sua voracidade.

  • Um átomo quantificado com quantificador de repetição fixo ({m} ou {m}?) tem a mesma voracidade (possivelmente nenhuma) que o próprio átomo.

  • Um átomo quantificado com outros quantificadores normais (incluindo {m,n} com m igual a n) é voraz (prefere a correspondência mais longa).

  • Um átomo quantificado com quantificador não voraz (incluindo {m,n}? m m igual a n) não é voraz (prefere a correspondência mais curta).

  • Um ramo — ou seja, uma RE que não tem operador | de nível superior — tem a mesma voracidade que o primeiro átomo quantificado que tem um atributo de voracidade.

  • Uma RE que consiste em dois ou mais ramos conectados pelo operador | é sempre voraz.

As regras acima associam atributos de voracidade não apenas a átomos quantificados individualmente, mas também a ramificações e REs inteiras que contêm átomos quantificados. O que isto significa é a correspondência ser feita de forma que a ramificação, ou toda a ER, corresponda à sub-cadeia de caracteres mais longa ou mais curta possível como um todo. Uma vez que o comprimento de toda a correspondência é determinado, a parte dela que corresponde a qualquer subexpressão específica é determinada com base no atributo de voracidade desta subexpressão, com subexpressões começando mais cedo na RE tendo prioridade sobre as que começam mais tarde.

Um exemplo do que isto significa:

SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
→ 123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
→ 1

No primeiro caso, a RE como um todo é voraz, porque Y* é voraz. Pode corresponder começando no Y, e corresponde à cadeia de caracteres mais longa possível começando nesta posição, ou seja, Y123. A saída é a parte entre parênteses disso, ou seja, 123. No segundo caso, a RE como um todo não é voraz, porque Y*? não é voraz. Pode corresponder começando no Y, e corresponde à cadeia de caracteres mais curta possível começando nesta posição, ou seja, Y1. A subexpressão [0-9]{1,3} é voraz, mas não pode mudar a decisão quanto ao comprimento da correspondência; por isto é forçada a corresponder apenas a 1.

Em suma, quando uma RE contém subexpressões vorazes e não vorazes, o comprimento total da correspondência é o maior ou o menor possível, conforme o atributo atribuído a toda a RE. Os atributos atribuídos às subexpressões afetam apenas o quanto desta correspondência eles podem comer em relação uns aos outros.

Os quantificadores {1,1} e {1,1}? podem ser usados para forçar a voracidade ou não voracidade, respectivamente, em uma subexpressão ou em uma RE inteira. Isto é útil quando há necessidade que todo a RE tenha um atributo de voracidade diferente do que é deduzido de seus elementos. Como exemplo, supondo que estamos tentando separar uma cadeia de caracteres contendo alguns dígitos nos dígitos e nas partes antes e depois deles. Podemos tentar fazer assim:

SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
→ {abc0123,4,xyz}

Isto não funcionou: o primeiro .* é voraz, então come o máximo que pode, deixando o \d+ para corresponder no último lugar possível, o último dígito. Podemos tentar consertar isto tornando-o não voraz:

SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
→ {abc,0,""}

Isto também não funcionou, porque agora a RE como um todo não é voraz e, por isto, termina a correspondência geral o mais rápido possível. Podemos conseguir o que queremos forçando a RE como um todo a ser voraz:

SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
→ {abc,01234,xyz}

Controlar a voracidade geral da RE de forma separada da voracidade de seus componentes, permite grande flexibilidade no tratamento de padrões de comprimento variável.

Ao decidir o que é uma correspondência mais longa ou mais curta, os comprimentos de correspondência são medidos em caracteres, não em elementos de ordenação. Uma cadeia de caracteres vazia é considerada mais longa que nenhuma correspondência. Por exemplo: bb* corresponde aos três caracteres do meio de abbbc; (week|wee)(night|knights) corresponde a todos os dez caracteres de weeknights; quando (.*).* é correspondido contra abc a subexpressão entre parênteses corresponde a todos os três caracteres; e quando (a*)* é correspondido contra bc tanto a RE inteira quanto a subexpressão entre parênteses correspondem a uma cadeia de caracteres vazia.

Se for especificada uma correspondência indiferente a letras maiúsculas e minúsculas, o efeito é como se todas as distinções de maiúsculas e minúsculas tivessem desaparecido do alfabeto. Quando um caractere alfabético, que aparece em várias formas, aparece como um caractere comum fora de uma expressão de colchetes, o caractere é transformado em uma expressão de colchetes contendo as duas formas; por exemplo, x se torna [xX]. Quando aparece em uma expressão de colchetes, todas as contrapartes maiúsculas são adicionadas à expressão de colchetes; por exemplo, [x] se torna [xX] e [^x] se torna [^xX].

Se for especificada uma correspondência sensível a nova linha, . e expressões de colchetes usando ^ nunca corresponderão ao caractere de nova linha (para que as correspondências não cruzem as linhas, a menos que a RE inclua explicitamente um caractere de nova linha) e ^ e $ corresponderão à cadeia de caracteres vazia após e antes de uma nova linha, respectivamente, além de corresponder no início e no final da cadeia de caracteres, respectivamente. Mas os escapes das ARE \A e \Z continuam a corresponder apenas no início e no final da cadeia de caracteres. Além disso, os atalhos de classe de caractere \D e \W corresponderão a uma nova linha independentemente deste modo. (Antes do PostgreSQL 14 não correspondiam a novas linhas quando no modo sensível a nova linha. Deve ser escrito [^[:digit:]] ou [^[:word:]] para obter o comportamento antigo.)

Se for especificada a correspondência parcial sensível a nova linha, isto afetará as expressões . e colchetes como na correspondência sensível à nova linha, mas não ^ e $.

Se for especificada a correspondência parcial inversa sensível a nova linha, isto afetará ^ e $ como na correspondência sensível a nova linha, mas não . e expressões de colchetes. Não é muito útil, mas é fornecido para simetria.

9.7.3.6. Limites e Compatibilidade #

Nenhum limite específico foi imposto ao comprimento das REs nesta implementação. No entanto, programas destinados a serem altamente portáveis não devem usar REs com mais de 256 bytes, porque uma implementação aderente ao POSIX vai se recusar a aceitar tais REs.

O único recurso das ARE que é realmente incompatível com as ERE do POSIX, é que a \ não perde seu significado especial dentro de expressões de colchetes. Todos os outros recursos das ARE usam uma sintaxe que é ilegal, ou tem efeitos indefinidos, ou não especificados, nas ERE do POSIX; a sintaxe diretora *** também está fora da sintaxe POSIX para as BRE e as ERE.

Muitas extensões das ARE foram pegas emprestadas do Perl, mas algumas foram modificadas para limpá-las, e algumas extensões do Perl não estão presentes. Incompatibilidades dignas de nota incluem: \b, \B, a falta de tratamento especial para uma nova linha no final, a adição de expressões de colchetes acrescidas às coisas afetadas pela correspondência sensível a nova linha, as restrições entre parênteses, as referências inversas nas restrições de avanço/recuo (lookahead/lookbehind) e a semântica de correspondência mais longa/mais curta (em vez de primeira correspondência).

9.7.3.7. Expressões regulares básicas #

As BRE diferem das ERE em vários aspectos. Nas BRE, |, + e ? são caracteres comuns, não havendo equivalente para suas funcionalidades. Os delimitadores de limites são \{ e \}, com { e } por si próprios sendo apenas caracteres comuns. Os parênteses para subexpressões aninhadas são \( e \), com ( e ) por si próprios sendo apenas caracteres comuns. ^ é um caractere comum, exceto no início da RE, ou no início de uma subexpressão entre parênteses, $ é um caractere comum, exceto no final da RE, ou no final de uma subexpressão entre parênteses, e * é um caractere comum, se aparecer no início da RE ou no início de uma subexpressão entre parênteses (após um possível ^ inicial). Por fim, estão disponíveis referências inversas de um dígito, e \< e \> são sinônimos de [[:<:]] e [[:>:]] respectivamente; nenhum outro escape está disponível nas BRE.

9.7.3.8. Diferenças entre o padrão SQL e o XQuery #

Desde o SQL:2008, o padrão SQL inclui operadores e funções de expressões regulares que realizam a correspondência de padrão de acordo com o padrão de expressões regulares XQuery.

  • LIKE_REGEX

  • OCCURRENCES_REGEX

  • POSITION_REGEX

  • SUBSTRING_REGEX

  • TRANSLATE_REGEX

No momento o PostgreSQL não implementa estes operadores e funções. Podem ser obtidas funcionalidades aproximadamente equivalentes em cada caso, conforme descrito na Tabela 9.25. (Foram omitidas nesta tabela diversas cláusulas opcionais de ambos os lados.)

Tabela 9.25. Equivalências entre funções de expressões regulares

Padrão SQLPostgreSQL
string LIKE_REGEX patternregexp_like(string, pattern) ou string ~ pattern
OCCURRENCES_REGEX(pattern IN string)regexp_count(string, pattern)
POSITION_REGEX(pattern IN string)regexp_instr(string, pattern)
SUBSTRING_REGEX(pattern IN string)regexp_substr(string, pattern)
TRANSLATE_REGEX(pattern IN string WITH replacement)regexp_replace(string, pattern, replacement)

Funções de expressão regular semelhantes às fornecidas pelo PostgreSQL também estão disponíveis em diversas outras implementações de SQL, enquanto as funções padrão do SQL não são tão amplamente implementadas. Alguns detalhes da sintaxe das expressões regulares provavelmente serão diferentes em cada implementação.

Os operadores e funções do padrão SQL usam expressões regulares XQuery, que são bastante semelhantes à sintaxe ARE descrita acima. As principais diferenças entre o recurso das expressões regulares existentes baseadas no POSIX e as expressões regulares XQuery incluem:

  • A subtração de classe de caracteres do XQuery não tem suporte. Um exemplo desse recurso é o uso da seguinte expressão para corresponder apenas às consoantes da língua inglesa: [a-z-[aeiou]].

  • Os atalhos de classe de caracteres do XQuery \c, \C, \i, e \I não têm suporte.

  • Elementos de classe de caracteres do XQuery usando \p{UnicodeProperty} ou o inverso \P{UnicodeProperty} não têm suporte.

  • O POSIX interpreta classes de caracteres como \w (veja a Tabela 9.21) segundo a localidade predominante (que pode ser controlada anexando uma cláusula COLLATE ao operador ou a função). O XQuery especifica estas classes por referência a propriedades de caracteres Unicode, portanto o comportamento equivalente é obtido somente com uma localidade que segue as regras do Unicode.

  • O padrão SQL (não o próprio XQuery) tenta atender a mais formas alternativas de nova-linha do que o POSIX. As opções de correspondência sensíveis a nova linha descritas acima consideram apenas o NL do ASCII (\n) como sendo o caractere de nova linha, mas o SQL nos faz tratar CR (\r), CRLF (\r\n) (nova linha no estilo Windows), e alguns caracteres somente do Unicode, como LINE SEPARATOR (U+2028), como nova linha também. Notadamente, . e \s devem contar \r\n como sendo um único caractere, e não dois, segundo o padrão SQL.

  • Dos escapes de entrada de caractere descritos na Tabela 9.20, o XQuery aceita apenas \n, \r e \t.

  • O XQuery não aceita a sintaxe [:nome:] para classes de caracteres dentro de expressões de colchetes.

  • O XQuery não contempla restrições de avanço e recuo (lookahead/lookbehind), nem qualquer um dos escapes de restrição descritos na Tabela 9.22.

  • As formas de metassintaxe descritas na Seção 9.7.3.4 não existem no XQuery.

  • As letras de sinalizador de expressão regular definidas pelo XQuery são relacionadas, mas não são idênticas às letras de opção do POSIX (Tabela 9.24). Enquanto as opções i e q se comportam da mesma maneira, outras não: [68]

    • Os sinalizadores s (permite que o ponto corresponda ao caractere de nova linha) e m (permite que ^ e $ correspondam no caractere de nova linha) do XQuery fornecem acesso aos mesmos comportamentos que os sinalizadores n, p e w do POSIX, mas não correspondem ao comportamento dos sinalizadores s e m do POSIX. Note, em particular, que ponto corresponder à nova linha é o comportamento padrão no POSIX, mas não no XQuery.

    • O sinalizador x do XQuery (ignorar o espaço em branco no padrão) é notadamente diferente do sinalizador de modo expandido do POSIX. O sinalizador x do POSIX também permite que # inicie um comentário no padrão, e o POSIX não ignora um caractere de espaço em branco após uma contrabarra.



[59] IBM DB2 - Expressões regulares: Uma expressão regular é uma sequência de caracteres que agem como um padrão para combinar e tratar cadeias de caracteres (N. T.)

[60] Condições de correspondência de padrões Amazon Redshift (N. T.)

[61] Metacaracteres Expressões regulares Perl (N. T.)

[62] POSIX - Portable Operating System Interface (N. T.)

[63] https://www.regular-expressions.info The Premier website about Regular Expressions (N. T.)

[64] backreference Um item em uma expressão regular equivalente ao texto correspondente a um padrão anterior na expressão. (N. T.)

[65] Construtores de referência inversa Uma referência inversa permite que uma subexpressão correspondida anteriormente seja identificada posteriormente na mesma expressão regular. (N. T.)

[66] [^abcd], [^a-d] – Corresponde a qualquer caractere, exceto aqueles que estiverem entre colchetes, ou em um intervalo de caracteres separados por um hífen (-). IBM – Expressões entre colchetes (N. T.)

[67] A ordem de classificação determina como os valores de dados são classificados. A ordem afeta os resultados da comparação de dados.(N. T.)

[68] IBM DB2 - XQuery fn:matches A função fn:matches determina se uma cadeia de caracteres corresponde a um padrão específico. (N. T.)