JavaRush /Blogue Java /Random-PT /Expressões regulares em Java, Parte 1

Expressões regulares em Java, Parte 1

Publicado no grupo Random-PT
Chamamos sua atenção para a tradução de um breve guia sobre expressões regulares na linguagem Java, escrito por Jeff Friesen para o site JavaWorld . Para facilitar a leitura, dividimos o artigo em várias partes. Expressões regulares em Java, Parte 1 - 1

Usando a API de expressão regular em programas Java para reconhecer e descrever padrões

O caractere do Java e vários tipos de dados de string fornecem suporte de baixo nível para correspondência de padrões, mas usá-los para essa finalidade normalmente adiciona complexidade significativa ao código. Código mais simples e de melhor desempenho é obtido usando a API Regex ("API de Expressão Regular"). Este tutorial ajudará você a começar a usar expressões regulares e a API Regex. Primeiro discutiremos as três classes mais interessantes do pacote em geral java.util.regexe, em seguida, daremos uma olhada no interior da classe Patterne exploraremos suas sofisticadas construções de correspondência de padrões. Atenção: Você pode baixar o código-fonte (criado por Jeff Friesen para o site JavaWorld) do aplicativo de demonstração deste artigo aqui .

O que são expressões regulares?

Uma expressão regular (expressão regular/regex/regexp) é uma string que é um padrão que descreve um determinado conjunto de strings. O padrão determina quais linhas pertencem ao conjunto. O padrão consiste em literais e metacaracteres – caracteres com um significado especial em vez de um significado literal. A correspondência de padrões é uma pesquisa de texto para encontrar correspondências, ou seja, strings que correspondam a um padrão de expressão regular. Java oferece suporte à correspondência de padrões por meio de sua API Regex. Esta API consiste em três classes: Patterne Matcher, PatternSyntaxExceptionlocalizadas no pacote java.util.regex:
  • objetos de classe Pattern, também chamados de modelos, são expressões regulares compiladas.
  • objetos de classe Matcher, ou matchers, são mecanismos de interpretação de padrões para encontrar correspondências em sequências de caracteres (objetos cujas classes implementam uma interface java.lang.CharSequencee servem como fontes de texto).
  • Objetos de classe PatternSyntaxExceptionsão usados ​​para descrever padrões de expressões regulares inválidos.
Java também fornece suporte para correspondência de padrões por meio de vários métodos do java.lang.String. Por exemplo, a função boolean matches (String regex)retorna trueapenas se a string de chamada corresponder exatamente à expressão regular regex.
Métodos convenientes
matches()e outros métodos de conveniência da classe orientados a expressões regulares Stringsão implementados internamente de maneira semelhante à API Regex.

Demonstração Regex

Criei um aplicativo RegexDemopara demonstrar expressões regulares Java e vários métodos de Pattern, Matchere PatternSyntaxException. Abaixo está o código-fonte deste aplicativo de demonstração. Listagem 1. Demonstração de expressão regular
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
public class RegexDemo
{
   public static void main(String[] args)
   {
      if (args.length != 2)
      {
         System.err.println("usage: java RegexDemo regex input");
         return;
      }
      // Преобразуем символьные последовательности начала новой строки (\n) в символы начала строки.
      args[1] = args[1].replaceAll("\\\\n", "\n");
      try
      {
         System.out.println("regex = " + args[0]);
         System.out.println("input = " + args[1]);
         Pattern p = Pattern.compile(args[0]);
         Matcher m = p.matcher(args[1]);
         while (m.find())
            System.out.println("Found [" + m.group() + "] starting at "
                               + m.start() + " and ending at " + (m.end() - 1));
      }
      catch (PatternSyntaxException pse)
      {
         System.err.println("Неправильное регулярное выражение: " + pse.getMessage());
         System.err.println("Описание: " + pse.getDescription());
         System.err.println("Позиция: " + pse.getIndex());
         System.err.println("Неправильный шаблон: " + pse.getPattern());
      }
   }
}
mainA primeira coisa que um método de classe faz RegexDemoé verificar sua linha de comando. Requer dois argumentos: o primeiro é uma expressão regular e o segundo é o texto de entrada no qual a expressão regular será pesquisada. Talvez seja necessário usar um caractere de nova linha no texto de entrada (\n). Isso só pode ser feito especificando o caractere \seguido do caractere n. A função main()converte essa sequência de caracteres no valor Unicode 10. Expressões regulares em Java, Parte 1 - 2A maior parte do código RegexDemoé colocada entre try-catch. O bloco tryprimeiro gera a expressão regular fornecida e o texto de entrada e, em seguida, cria um objeto Patternque armazena a expressão regular compilada (expressões regulares são compiladas para melhorar o desempenho da correspondência de padrões). Um matcher é extraído do objeto Patterne usado para procurar correspondências iterativamente até que todas sejam encontradas. O bloco catchchama vários métodos de classe PatternSyntaxExceptionpara recuperar informações úteis sobre a exceção. Essas informações são enviadas sequencialmente para o fluxo de saída. Não há necessidade de conhecer ainda os detalhes de como o código funciona: eles ficarão claros quando estudarmos a API na segunda parte do artigo. No entanto, você deve compilar a Listagem 1. Pegue o código da Listagem 1 e digite o seguinte comando no prompt de comando para compilar RegexDemo: javac RegexDemo.java

A classe Pattern e suas construções

A classe Pattern, a primeira das três classes que compõem a API Regex, é uma representação compilada de uma expressão regular. A documentação do SDK da classe Patterndescreve uma variedade de construções de expressões regulares, mas se você não usar expressões regulares ativamente, partes desta documentação poderão ser confusas. O que são quantificadores e qual é a diferença entre quantificadores gananciosos, relutantes e possessivos? O que são classes de caracteres, correspondências de limites, referências anteriores e expressões de sinalizadores incorporadas? Responderei a essas e outras perguntas nas seções a seguir.

Sequências literais

A construção de expressão regular mais simples é uma string literal. Para que a correspondência de padrões seja bem-sucedida, alguma parte do texto de entrada deve corresponder ao padrão dessa construção. Considere o seguinte exemplo: java RegexDemo apple applet Neste exemplo, estamos tentando encontrar uma correspondência para um padrão appleno texto de entrada applet. O resultado a seguir mostra a correspondência encontrada:
regex = apple
input = applet
Found [apple] starting at 0 and ending at 4
Vemos na saída a expressão regular e o texto de entrada e, em seguida, uma indicação de detecção bem-sucedida appleno miniaplicativo. Além disso, são fornecidas as posições inicial e final desta partida: 0e 4, respectivamente. A posição inicial indica o primeiro lugar no texto onde uma correspondência foi encontrada e a posição final indica o último ponto da correspondência. Agora digamos que demos a seguinte linha de comando: java RegexDemo apple crabapple Desta vez obtemos o seguinte resultado, com diferentes posições inicial e final:
regex = apple
input = crabapple
Found [apple] starting at 4 and ending at 8
Caso contrário, com e appletcomo expressão regular apple- o texto de entrada, nenhuma correspondência será encontrada. Toda a expressão regular deve corresponder, mas neste caso, o texto de entrada não contém tafter apple. Expressões regulares em Java, Parte 1 - 3

Metacaracteres

Construções de expressões regulares mais interessantes combinam caracteres literais com metacaracteres. Por exemplo, em uma expressão regular a.b, o metacaractere ponto (.)significa qualquer caractere entre ae b. Considere o seguinte exemplo: java RegexDemo .ox "The quick brown fox jumps over the lazy ox." Este exemplo usa .oxcomo expressão regular e The quick brown fox jumps over the lazy ox.como texto de entrada. RegexDemopesquisa o texto em busca de correspondências começando com qualquer caractere e terminando com ox.Os resultados de sua execução são os seguintes:
regex = .ox
input = The quick brown fox jumps over the lazy ox.
Found [fox] starting at 16 and ending at 18
Found [ ox] starting at 39 and ending at 41
Na saída vemos duas correspondências: foxe ox(com um caractere de espaço na frente). O metacaractere . corresponde a um caractere fno primeiro caso e a um espaço no segundo. O que acontece se você substituí-lo .oxpor um metacaractere .? Isto é, o que obtemos como resultado da seguinte linha de comando: java RegexDemo . "The quick brown fox jumps over the lazy ox." Como o metacaractere ponto corresponde a qualquer caractere, RegexDemoproduzirá as correspondências encontradas para todos os caracteres (incluindo o caractere ponto final) do texto de entrada:
regex = .
input = The quick brown fox jumps over the lazy ox.
Found [T] starting at 0 and ending at 0
Found [h] starting at 1 and ending at 1
Found [e] starting at 2 and ending at 2
Found [ ] starting at 3 and ending at 3
Found [q] starting at 4 and ending at 4
Found [u] starting at 5 and ending at 5
Found [i] starting at 6 and ending at 6
Found [c] starting at 7 and ending at 7
Found [k] starting at 8 and ending at 8
Found [ ] starting at 9 and ending at 9
Found [b] starting at 10 and ending at 10
Found [r] starting at 11 and ending at 11
Found [o] starting at 12 and ending at 12
Found [w] starting at 13 and ending at 13
Found [n] starting at 14 and ending at 14
Found [ ] starting at 15 and ending at 15
Found [f] starting at 16 and ending at 16
Found [o] starting at 17 and ending at 17
Found [x] starting at 18 and ending at 18
Found [ ] starting at 19 and ending at 19
Found [j] starting at 20 and ending at 20
Found [u] starting at 21 and ending at 21
Found [m] starting at 22 and ending at 22
Found [p] starting at 23 and ending at 23
Found [s] starting at 24 and ending at 24
Found [ ] starting at 25 and ending at 25
Found [o] starting at 26 and ending at 26
Found [v] starting at 27 and ending at 27
Found [e] starting at 28 and ending at 28
Found [r] starting at 29 and ending at 29
Found [ ] starting at 30 and ending at 30
Found [t] starting at 31 and ending at 31
Found [h] starting at 32 and ending at 32
Found [e] starting at 33 and ending at 33
Found [ ] starting at 34 and ending at 34
Found [l] starting at 35 and ending at 35
Found [a] starting at 36 and ending at 36
Found [z] starting at 37 and ending at 37
Found [y] starting at 38 and ending at 38
Found [ ] starting at 39 and ending at 39
Found [o] starting at 40 and ending at 40
Found [x] starting at 41 and ending at 41
Found [.] starting at 42 and ending at 42
Citar metacaracteres
Para especificar .qualquer outro metacaractere como um caractere literal em uma construção de expressão regular, você deve escapar dele de uma das seguintes maneiras:
  • preceda-o com uma barra invertida;
  • Coloque este metacaractere entre \Qe \E(por exemplo, \Q.\E).
Lembre-se de duplicar todos os caracteres que aparecem na string literal, como String regex = "\\.";barras invertidas (por exemplo, \\.ou \\Q.\\E). Não duplique as barras invertidas que fazem parte de um argumento de linha de comando.

Classes de personagens

Às vezes você tem que limitar as correspondências que procura a um conjunto específico de caracteres. Por exemplo, pesquise no texto as vogais a, e, e , sendo cada ocorrência de uma letra vocálica considerada uma correspondência i. Na resolução de tais problemas, seremos auxiliados por classes de caracteres que definem conjuntos de caracteres entre os metacaracteres dos colchetes ( ). A classe oferece suporte a classes de caracteres simples, classes de intervalo, classes inversas, de união, interseção e subtração. Veremos todos eles agora. ou[ ]Pattern

Classes de caracteres simples

Uma classe de caracteres simples consiste em caracteres colocados lado a lado e corresponde apenas a esses caracteres. Por exemplo, a classe [abc]corresponde aos caracteres ae . Considere o seguinte exemplo: Como você pode ver nos resultados, neste exemplo apenas o caractere para o qual há uma correspondência em : bcjava RegexDemo [csw] caveccave
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0

Classes de personagens invertidos

Uma classe de caracteres invertidos começa com um metacaractere ^e corresponde apenas aos caracteres não contidos nele. Por exemplo, a classe [^abc]corresponde a todos os caracteres, exceto a, be c. Considere o seguinte exemplo: java RegexDemo "[^csw]" cave Observe que no meu sistema operacional (Windows) são necessárias aspas duplas porque o shell as trata ^como um caractere de escape. Como você pode ver, neste exemplo foram encontrados apenas os caracteres a, ve e, para os quais há correspondências em cave:
regex = [^csw]
input = cave
Found [a] starting at 1 and ending at 1
Found [v] starting at 2 and ending at 2
Found [e] starting at 3 and ending at 3

Classes de personagens de alcance

Uma classe de caracteres de intervalo consiste em dois caracteres separados por um hífen ( -). Todos os caracteres, começando com o caractere à esquerda do hífen e terminando com o caractere à direita, fazem parte do intervalo. Por exemplo, o intervalo [a-z]corresponde a todas as letras latinas minúsculas. Isso equivale a definir uma classe simples [abcdefghijklmnopqrstuvwxyz]. Considere o seguinte exemplo: java RegexDemo [a-c] clown Este exemplo corresponderá apenas ao caractere cque corresponde a clown:
regex = [a-c]
input = clown
Found [c] starting at 0 and ending at 0
Expressões regulares em Java, Parte 2 Expressões regulares em Java, Parte 3 Expressões regulares em Java, Parte 4 Expressões regulares em Java, Parte 5
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION