# Expressões Regulares

     Este Apêndice contém uma breve mas abrangente e suficiente introdução
    ao mundo das expressões regulares. Ela documenta as
    expressões regulares na forma que está disponível no &kate;, a qual não é
    compatível com as expressões regulares do Perl, nem com as do
    grep, por exemplo.

## Introdução

As Expressões Regulares oferecem-nos uma forma de descrever alguns conteúdos possíveis de uma sequência de texto, a qual pode ser compreendida de certa forma por algum 'software', de modo a que este possa investigar se um texto corresponde, e também no caso das aplicações avançadas, com a possibilidade de guardar pedaços do texto correspondente.

Um exemplo: Imagina que queres procurar num texto por parágrafos que comecem quer pelos nomes Henrique ou Pedro seguidos de alguma forma do verbo dizer.

Com uma pesquisa normal, irias começar a procurar pelo primeiro nome, Henrique sendo talvez seguido de di como o seguinte: `Henrique di`, e enquanto procuras por correspondências, irias ignorar os que não se encontram no início de um parágrafo, assim como os que têm uma palavra que começa por di que não é diz, disse ou algo do género. Claro, e ainda teres que repetir isto com o próximo nome...

Com as Expressões Regulares, essa tarefa pode ser acompanhada com uma única pesquisa e com um maior grau de precisão.

Para conseguir isto, as Expressões Regulares definem regras para exprimir com detalhe uma generalização de uma sequência de texto com a qual corresponder. No nosso exemplo, o qual podemos exprimir literalmente da seguinte forma: Uma linha que começa por Henrique ou Pedro (possivelmente a seguir a 4 espaços ou tabulações) seguida de um espaço em branco e da sequência di, sendo esta seguida de z ou sse pode ser expressa com a seguinte expressão regular:

`^[ \t]{0,4}(Henrique|Pedro) di(z|sse)`

O exemplo anterior demonstra todos os quatro maiores conceitos das expressões regulares modernas, nomeadamente:

- Padrões

- Asserções

- Quantificadores

- Referências anteriores

O acento circunflexo (`^`) no início da expressão é uma asserção ou verificação que é verdadeira só se o texto correspondente está no início da linha.

As sequências `[ \t]` e `(Henrique|Pedro) di(z|se)` são padrões. O primeiro é uma classe de caracteres que corresponde quer a um espaço em branco quer a uma tabulação (horizontal); o outro padrão contém em primeiro lugar um sub-padrão que corresponde quer a `Henrique` quer a `Pedro`, pelo que se segue o texto exacto `di` e finalmente existe um sub-padrão que corresponde a `z` ou a `sse`

A sequência `{0,4}` é um quantificador que diz qualquer número de vezes entre 0 e 4 da sequência anterior.

Como o 'software' de expressões regulares suporta o conceito de referências anteriores guarda a parte inteira correspondente ao texto, bem como aos sub-padrões entre parêntesis, se for dado um meio de aceder a essas referências, pode-se aceder a toda a correspondência (ao procurar num documento de texto num edit com uma expressão regular, esta é normalmente marcada como seleccionada), apenas ao nome encontrado, ou à última parte do verbo.

Tudo em conjunto, a expressão irá corresponder onde nós queiramos que o faça, e só aí.

As secções seguintes irão descrever em detalhe como construir e usar os padrões, as classes de caracteres, as verificações, os quantificadores e as referências anteriores; a secção final irá dar alguns exemplos úteis.

## Padrões

Os padrões consistem em cadeias de caracteres literais e em classes de caracteres. Os padrões podem conter sub-padrões, que são padrões entre parêntesis.

### Caracteres de escape

Tanto nos padrões como nas classes de caracteres, alguns caracteres têm um significado especial. Para corresponder literalmente com algum desses caracteres, estes têm de ser marcados ou escapados para permitir ao 'software' de expressões regulares perceber que deve interpretar esses caracteres no seu sentido literal.

Isto é feito antecedendo o carácter com uma barra invertida (`\`).

O 'software' de expressões regulares irá ignorar silenciosamente uma barra para um carácter que não tenha um significado especial no contexto, por isso se escapares, por exemplo, um j (`\j`) não há problema. Se tens dúvidas se um carácter poderá ter algum significado especial, podes então escapá-lo em segurança.

### Classes de Caracteres e abreviaturas

Uma classe de caracteres é uma expressão que corresponde a um carácter dentro de um conjunto definido de caracteres. Nas Expressões Regulares, as classes de caracteres são definidas pondo os caracteres permitidos para a classe entre parêntesis rectos, `[]`, ou usando uma das classes abreviadas descritas em seguida:

As classes de caracteres simples contêm apenas um ou mais caracteres literais, como por exemplo `[abc]` (o que pode corresponder quer a a, a b ou a c), ou então o `[0123456789]` (que corresponde a qualquer dígito).

Dado que as letras e os números têm uma ordem lógica, podes abreviá-los especificando intervalos: `[a-c]` é igual a `[abc]` e `[0-9]` é igual a `[0123456789]`. Combinando estas opções, por exemplo `[a-fynot1-38]` é perfeitamente possível (a última classe irá corresponder a um dos seguintes caracteres: a,b,c,d, e,f,y,n,o,t, 1,2,3 ou 8).

Dado que as letras maiúsculas são caracteres diferentes dos seus equivalentes minúsculos, para criares uma classe de caracteres indiferente da capitalização que corresponda quer a a ou a b em qualquer dos casos, necessitas de a indicar como `[aAbB]`.

Obviamente, é possível criar uma classe negativa que corresponda a tudo excepto. Para o fazeres põe um acento circunflexo (`^`) no início da classe:

`[^abc]` irá corresponder a qualquer carácter excepto o a, b ou c.

Para além dos caracteres literais, estão definidas algumas abreviaturas, o que torna a vida um pouco mais fácil:

`\a`

  Isto corresponde ao carácter ASCII da campainha (BEL, 0x07).

`\f`

  Isto corresponde ao carácter ASCII de 'form feed' (FF, 0x0C).

`\n`

  Isto corresponde ao carácter ASCII de 'line feed' (LF, 0x0A, a mudança de linha do Unix).

`\r`

  Isto corresopnde ao carácter ASCII de 'carriage return' (CR, 0x0D).

`\t`

  Isto corresponde ao carácter ASCII de tabulação horizontal (HT, 0x09).

`\v`

  Isto corresponde ao carácter ASCII de tabulação vertical (VT, 0x0B).

`\xhhhh`

  Isto corresponde ao carácter Unicode com o código hexadecimal hhhh (entre 0x0000 e 0xFFFF). O \0ooo (isto é, \zero ooo) corresponde ao carácter ASCII/Latin-1 com o código octal ooo (entre 0 e 0377).

`.` (ponto)

  Isto corresponde a qualquer carácter (mesmo a mudança de linha).

`\d`

  Corresponde a um dígito. É igual a `[0-9]`

`\D`

  Corresponde a um não-dígito. É igual a `[^0-9]` ou `[^\d]`

`\s`

  Corresponde a um carácter em branco. É praticamente igual a `[ \t\n\r]`

`\S`

  Corresponde a um carácter não-branco. É praticamente igual a `[^ \t\r\n]` e igual a `[^\s]`

`\w`

  Corresponde a qualquer carácter de palavra - neste caso, qualquer letra ou dígito. Repara que o sublinhado (`_`) não corresponde, como acontece com as expressões regulares do Perl. É igual a `[a-zA-Z0-9]`

`\W`

  Corresponde a um não-carácter de palavra - tudo menos letras ou dígitos. É igual a `[^a-zA-Z0-9]` ou `[^\w]`

As classes abreviadas podem ser postas dentro de uma classe personalizada, por exemplo para corresponder a um carácter de palavra, a um espaço em branco ou a um ponto, poderias escrever `[\w \.]`

A notação POSIX das classes, `[:<nome da classe>:]` não é suportada de momento.

#### Os carácter com significados especiais dentro de classes de caracteres

Os seguintes caracteres têm um significado especial dentro da estrutura da classe de caracteres [], e devem ser escapados para serem incluídos literalmente dentro de uma classe:

`]`

  Termina a classe de caracteres. Deve ser escapada a menos que seja o primeiro carácter da classe (pode estar a seguir a um ^ não-escapado)

`^` (acento circunflexo)

  Denota uma classe negativa, se for o primeiro carácter. Deve ser escapado para ser correspondido literalmente, se for o primeiro carácter da classe.

`-` (traço)

  Denota um intervalo lógio. Deve estar sempre escapado numa classe de caracteres.

`\` (barra invertida)

  O carácter de escape. Deve ser sempre escapado.

### Alternativas: corresponder a um de

Se quiseres corresponder a um de um conjunto de padrões alternativos, podes separá-los com o `|` (carácter de barra vertical).

Por exemplo, se quiseres encontrar tanto João como Henrique poderás usar uma expressão `João|Henrique`.

### Sub-Padrões

Os sub-padrões são padrões colocados dentro de parêntesis, e podem ter várias utilizações no mundo das expressões regulares.

#### Especificar alternativas

Podes usar um sub-padrão para agrupar um conjunto de alternativas num padrão maior. As alternativas são separadas pelo carácter | (barra vertical).

Por exemplo, para corresponder a uma das palavras int, float ou double, podias usar o padrão `int|float|double`. Se só quiseres encontrar uma se estiver seguida de algum espaço e de algumas letras, põe as alternativas dentro de um sub-padrão: `(int|float|double)\s+\w+`.

#### Capturar o texto correspondente (referências anteriores)

Se quiseres usar uma referência anterior, usa um sub-padrão para obteres a parte desejada do padrão recordado.

Por exemplo, se quiseres encontrar duas ocorrências da mesma palavra separadas por uma vírgula e provavelmente por algum espaço, podias escrever `(\w+),\s*\1`. O sub-padrão `\w+` iria encontrar um conjunto de caracteres de palavra e a expressão inteira iria corresponder se estas fossem seguidas por uma vírgula, 0 ou mais espaços e por um conjunto igual de caracteres de palavras. (O texto `\1` referencia o primeiro sub-padrão entre parêntesis)

Vê também as Referências anteriores.

#### Verificações Antecipadas

Uma verificação antecipada é um sub-padrão que começa por `?=` ou por `?!`.

Por exemplo, para fazer a correspondência com o nome Bill mas só se não for seguido de Gates, podias usar esta expressão: `Bill(?! Gates)`. (Isto iria encontrar o Bill Clinton assim como o Billy the kid, mas iria ignorar as outras correspondências).

Os sub-padrões usados para as verificações não são capturados.

Vê também as Asserções ou Verificações

### Os caracteres com um significado especial dentro de padrões

Os seguintes caracteres têm significado próprio dentro de um padrão, e necessitam ser escapados se quiseres fazer correspondência com eles:

`\` (barra invertida)

  O carácter de escape.

`^` (acento circunflexo)

  Corresponde ao início do texto.

`$`

  Verifica o fim do texto.

`()` (parênteses esquerdo e direito)

  Denota os sub-padrões.

`{}` (chavetas esquerda e direita)

  Denota os quantificadores numéricos.

`[]` (parênteses rectos esquerdo e direito)

  Denota as classes de caracteres.

`|` (barra vertical)

  OU lógico. Separa alternativas.

`+` (sinal mais)

  Quantificador, 1 ou mais.

`*` (asterisco)

  Quantificador, 0 ou mais.

`?` (ponto de interrogação)

  Um carácter opcional. Pode ser interpretado como um quantificador 0 ou 1.

## Quantificadores

Os quantificadores permitem a uma expressão regular fazer a correspondência com um número ou intervalo específico de vezes nas quais ocorre um carácter, classe de caracteres ou sub-padrão.

Os quantificadores estão delimitados entre chavetas (`{` e `}`) e têm a forma geral `{[mínimo-de-ocorrências][,[máximo-de-ocorrências]]}`

A utilização será melhor explicada com um exemplo:

`{1}`

  Exactamente 1 ocorrência

`{0,1}`

  Zero ou 1 ocorrências

`{,1}`

  O mesmo, mas com menos trabalho ;)

`{5,10}`

  Pelo menos 5 mas no máximo 10 ocorrências

`{5,}`

  Pelo menos 5 ocorrências, sem máximo.

Adicionalmente, existem algumas abreviaturas:

`*` (asterisco)

  semelhante a `{0,}`, encontra qualquer número de ocorrências.

`+` (sinal mais)

  semelhante a `{1,}`, pelo menos 1 ocorrência.

`?` (ponto de interrogação)

  semelhante a `{0,1}`, zero ou uma ocorrências.

### Ganância

Ao usares quantificadores sem máximos, as expressões regulares tentam corresponder com o máximo do texto possível, um comportamente designado normalmente como greedy (ambicioso).

O 'software' de expressões regulares moderno oferece os desligar esse comportamento, ainda que num ambiente gráfico, isto dependa da interface que deres para a funcionalidade. Por exemplo, uma janela de procura que oferece uma pesquisa de expressões regulares poderia ter uma opção chamada Correspondência mínima, assim como podia indicar se o comportamento ambicioso é o comportamento por omissão.

### Exemplos no contexto

Aqui estão alguns exemplos da utilização de quantificadores

`^\d{4,5}\s`

  Corresponde aos dígitos em 1234 go e em 12345 now, mas não corresponde a 567 eleven ou a 223459 somewhere

`\s+`

  Corresponde a um ou mais caracteres em branco

`(bla){1,}`

  Corresponde a tudo de blablabla e a bla em blackbird ou em tabla

`/?>`

  Corresponde a /> em <closeditem/> assim como a > em <openitem>.

## Asserções

As verificações permitem a uma expressão regular fazer a correspondência apenas sob determinadas condições controladas.

Uma verificação não precisa de um carácter com o qual corresponder; em vez disso, verifica os limites de uma possível correspondência antes de a indicar. Por exemplo, a verificação de limite de palavra não tenta encontrar um carácter não pertencente a uma palavra junto com um carácter de palavra, mas sim tenta ter a certeza que não existe um carácter de palavra. Isto significa que a verificação pode corresponder onde não existir um carácter, isto é, no fim do texto a pesquisar.

Algumas verificações de facto têm um padrão de correspondência, mas a parte do texto que correspondeu não será uma parte do resultado da correspondência, em relação à expressão completa.

As Expressões Regulares aqui referidas suportam as seguintes verificações:

`^` (acento circunflexo: início do texto)

  Corresponde ao início do texto a pesquisar.

  A expressão `^Pedro` irá corresponder a Pedro no texto Pedro, olá! mas não em Olá, Pedro!

`$` (fim do texto)

  Corresponde ao fim do texto a pesquisar.

  A expressão `tu\?$` irá corresponder ao último 'tu' no texto tu não fizeste isto, ou foste tu? mas não fará correspondência em tu não fizeste isto, certo?

`\b` (limite de palavra)

  Corresponde a um limite de palavra de um lado e se não é um carácter de palavra do outro.

  Isto é útil para encontrar limites das palavras, como por exemplo ambos os extremos para encontrar uma palavra inteira. A expressão `\bem\b` irá corresponde ao em separado no texto Ele entrou em Enfermagem, mas não corresponder a em na palavra Enfermagem.

`\B` (não-limite de palavra)

  Corresponde nos locais onde o \b não faz correspondência.

  Isto significa que ele irá fazer correspondência, por exemplo, dentro de palavras. A expressão `\Bem\B` irá corresponder a sempre mas não a cem ou a Estou em casa.

`(?=PADRÃO)` (Antevisão positiva)

  Uma verificação antecipada olha para a parte do texto a seguir a uma possível correspondência. A antecipação positiva irá evitar que o texto corresponda se o texto que se encontra a seguir a possível correspondência não corresponder ao PADRÃO da verificação; o texto correspondente não será incluído no resultado.

  A expressão `utilizar(?=\w)` irá corresponder a utilizar em utilizarei mas não irá corresponder com Não vou utilizar!

`(?!PADRÃO)` (Antevisão Negativa)

  A antecipação negativa evita que uma possível correspondência seja extraída se a parte subsequente ao texto procurado corresponde ao PADRÃO.

  A expressão `const \w+\b(?!\s*&)` irá corresponder com o const char do texto const char* ola enquanto que não irá corresponder a const QString em const QString& bar porque o & corresponde ao padrão de verificação antecipada negativa.

## Referências Anteriores