JavaRush /Java Blog /Random-IT /Espressioni regolari in Java, parte 1

Espressioni regolari in Java, parte 1

Pubblicato nel gruppo Random-IT
Portiamo alla vostra attenzione la traduzione di una breve guida alle espressioni regolari nel linguaggio Java, scritta da Jeff Friesen per il sito JavaWorld . Per facilitare la lettura abbiamo diviso l’articolo in più parti. Espressioni regolari in Java, parte 1 - 1

Utilizzo dell'API delle espressioni regolari nei programmi Java per riconoscere e descrivere modelli

I caratteri Java e i vari tipi di dati stringa forniscono un supporto di basso livello per la corrispondenza dei modelli, ma il loro utilizzo per questo scopo in genere aggiunge una notevole complessità al codice. Un codice più semplice e più performante si ottiene utilizzando l'API Regex ("API delle espressioni regolari"). Questo tutorial ti aiuterà a iniziare con le espressioni regolari e l'API Regex. Discuteremo innanzitutto le tre classi più interessanti del pacchetto in generale java.util.regex, quindi daremo uno sguardo all'interno della classe Patterned esploreremo i suoi sofisticati costrutti di corrispondenza dei modelli. Attenzione: Puoi scaricare il codice sorgente (creato da Jeff Friesen per il sito JavaWorld) dell'applicazione demo da questo articolo da qui .

Cosa sono le espressioni regolari?

Un'espressione regolare (espressione regolare/regex/regexp) è una stringa che è un modello che descrive un determinato insieme di stringhe. Il modello determina quali righe appartengono al set. Il modello è costituito da letterali e metacaratteri, ovvero caratteri con un significato speciale piuttosto che letterale. La corrispondenza dei modelli è una ricerca di testo per trovare corrispondenze, ovvero stringhe che corrispondono a un modello di espressione regolare. Java supporta la corrispondenza dei modelli tramite la sua API Regex. Questa API è composta da tre classi: Pattern, Matchere PatternSyntaxException, situate nel pacchetto java.util.regex:
  • gli oggetti classe Pattern, chiamati anche modelli, sono espressioni regolari compilate.
  • gli oggetti di classe Matcher, o matcher, sono meccanismi di interpretazione di modelli per trovare corrispondenze in sequenze di caratteri (oggetti le cui classi implementano un'interfaccia java.lang.CharSequencee fungono da sorgenti di testo).
  • Gli oggetti classe PatternSyntaxExceptionvengono utilizzati per descrivere modelli di espressioni regolari non validi.
Java fornisce anche il supporto per la corrispondenza dei modelli attraverso vari metodi di java.lang.String. Ad esempio, la funzione boolean matches (String regex)restituisce truesolo se la stringa chiamante corrisponde esattamente all'espressione regolare regex.
Metodi convenienti
matches()e altri metodi pratici orientati alle espressioni regolari della classe Stringsono implementati dietro le quinte in modo simile all'API Regex.

RegexDemo

Ho creato un'applicazione RegexDemoper dimostrare le espressioni regolari Java e vari metodi di Pattern, Matchere PatternSyntaxException. Di seguito è riportato il codice sorgente per questa applicazione demo. Listato 1. Dimostrazione delle espressioni regolari
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());
      }
   }
}
La prima cosa che fa un metodo di mainclasse RegexDemoè controllare la sua riga di comando. Richiede due argomenti: il primo è un'espressione regolare e il secondo è il testo di input in cui verrà cercata l'espressione regolare. Potrebbe essere necessario utilizzare un carattere di nuova riga nel testo di input (\n). Questo può essere fatto solo specificando il carattere \seguito dal carattere n. La funzione main()converte questa sequenza di caratteri nel valore Unicode 10. Espressioni regolari in Java, parte 1 - 2La maggior parte del codice RegexDemoè racchiusa tra i caratteri try-catch. Il blocco tryinnanzitutto restituisce l'espressione regolare data e il testo di input, quindi crea un oggetto Patternche memorizza l'espressione regolare compilata (le espressioni regolari vengono compilate per migliorare le prestazioni di corrispondenza dei modelli). Un matcher viene estratto dall'oggetto Patterne utilizzato per cercare le corrispondenze in modo iterativo finché non vengono trovate tutte. Il blocco catchchiama diversi metodi di classe PatternSyntaxExceptionper recuperare informazioni utili sull'eccezione. Queste informazioni vengono inviate in sequenza al flusso di output. Non è ancora necessario conoscere i dettagli di come funziona il codice: diventeranno chiari quando studieremo l'API nella seconda parte dell'articolo. Tuttavia, è necessario compilare il Listato 1. Prendi il codice dal Listato 1, quindi digita il seguente comando al prompt dei comandi per compilare RegexDemo: javac RegexDemo.java

La classe Pattern e i suoi costrutti

La classe Pattern, la prima delle tre classi che compongono l'API Regex, è una rappresentazione compilata di un'espressione regolare. La documentazione dell'SDK della classe Patterndescrive una varietà di costrutti di espressioni regolari, ma se non utilizzi attivamente le espressioni regolari, parti di questa documentazione potrebbero creare confusione. Cosa sono i quantificatori e qual è la differenza tra quantificatori avidi, riluttanti e possessivi? Cosa sono le classi di caratteri, i corrispondenti di confine, i riferimenti all'indietro e le espressioni di flag incorporate? Risponderò a queste e ad altre domande nelle sezioni seguenti.

Stringhe letterali

Il costrutto di espressione regolare più semplice è una stringa letterale. Affinché la corrispondenza del modello abbia successo, una parte del testo di input deve corrispondere al modello di quel costrutto. Considera il seguente esempio: java RegexDemo apple applet in questo esempio, stiamo cercando di trovare una corrispondenza per un modello applenel testo di input applet. Il seguente risultato mostra la corrispondenza trovata:
regex = apple
input = applet
Found [apple] starting at 0 and ending at 4
Nell'output vediamo l'espressione regolare e il testo di input, quindi un'indicazione del rilevamento riuscito applenell'applet. Inoltre, vengono fornite le posizioni iniziale e finale di questa partita: 0e 4, rispettivamente. La posizione iniziale indica il primo punto del testo in cui è stata trovata una corrispondenza, mentre la posizione finale indica l'ultimo punto della corrispondenza. Ora diciamo di aver dato la seguente riga di comando: java RegexDemo apple crabapple Questa volta otteniamo il seguente risultato, con posizioni iniziali e finali diverse:
regex = apple
input = crabapple
Found [apple] starting at 4 and ending at 8
Altrimenti, con e appletcome espressione regolare apple- testo di input, non verrà trovata alcuna corrispondenza. L'intera espressione regolare deve corrispondere, ma in questo caso il testo di input non contiene tafter apple. Espressioni regolari in Java, parte 1 - 3

Metacaratteri

Costrutti di espressioni regolari più interessanti combinano caratteri letterali con metacaratteri. Ad esempio, in un'espressione regolare a.b, il metacarattere punto (.)indica qualsiasi carattere compreso tra ae b. Considera l'esempio seguente: java RegexDemo .ox "The quick brown fox jumps over the lazy ox." questo esempio utilizza .oxsia come espressione regolare che The quick brown fox jumps over the lazy ox.come testo di input. RegexDemocerca nel testo corrispondenze che iniziano con qualsiasi carattere e finiscono con. ox.I risultati della sua esecuzione sono i seguenti:
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
Nell'output vediamo due corrispondenze: foxe ox(con uno spazio davanti). Il metacarattere . corrisponde a un carattere fnel primo caso e a uno spazio nel secondo. Cosa succede se lo sostituisci .oxcon un metacarattere .? Cioè, ciò che otteniamo come risultato della seguente riga di comando: java RegexDemo . "The quick brown fox jumps over the lazy ox." Poiché il metacarattere punto corrisponde a qualsiasi carattere, RegexDemoverranno restituite le corrispondenze trovate per tutti i caratteri (incluso il carattere punto finale) del testo di input:
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
Metacaratteri delle citazioni
Per specificare .qualsiasi altro metacarattere come carattere letterale in un costrutto di espressione regolare, è necessario eseguirne l'escape in uno dei seguenti modi:
  • precederlo con un carattere barra rovesciata;
  • Posiziona questo metacarattere tra \Qe \E(ad esempio, \Q.\E).
Ricordarsi di duplicare tutti i caratteri che appaiono nella stringa letterale, come String regex = "\\.";le barre rovesciate (ad esempio, \\.o \\Q.\\E). Non duplicare le barre rovesciate che fanno parte di un argomento della riga di comando.

Classi di caratteri

A volte devi limitare le corrispondenze che stai cercando a un set specifico di caratteri. Ad esempio, cercare nel testo le vocali a, e, i, oe u, considerando ogni occorrenza di una lettera vocale una corrispondenza. Nella risoluzione di tali problemi saremo aiutati dalle classi di caratteri che definiscono insiemi di caratteri tra i metacaratteri delle parentesi quadre ( [ ]). La classe Patternsupporta classi di caratteri semplici, classi di intervallo, classi inverse, di unione, di intersezione e di sottrazione. Li esamineremo tutti adesso.

Classi di caratteri semplici

Una classe di caratteri semplice è composta da caratteri affiancati e corrisponde solo a tali caratteri. Ad esempio, la classe [abc]corrisponde ai caratteri a, be c. Considera il seguente esempio: java RegexDemo [csw] cave Come puoi vedere dai risultati, in questo esempio solo il carattere cper il quale esiste una corrispondenza in cave:
regex = [csw]
input = cave
Found [c] starting at 0 and ending at 0

Classi di caratteri invertite

Una classe di caratteri invertita inizia con un metacarattere ^e corrisponde solo ai caratteri non contenuti in esso. Ad esempio, la classe [^abc]corrisponde a tutti i caratteri tranne a, be c. Considera il seguente esempio: java RegexDemo "[^csw]" cave Nota che sul mio sistema operativo (Windows) sono necessarie le virgolette doppie perché la shell le tratta ^come un carattere di escape. Come puoi vedere, in questo esempio sono stati trovati solo i caratteri a, ve e, per i quali esistono corrispondenze in 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

Classi di caratteri di intervallo

Una classe di caratteri di intervallo è composta da due caratteri separati da un trattino ( -). Tutti i caratteri, a partire dal carattere a sinistra del trattino e terminando con il carattere a destra, fanno parte dell'intervallo. Ad esempio, l'intervallo [a-z]corrisponde a tutte le lettere latine minuscole. Ciò equivale a definire una classe semplice [abcdefghijklmnopqrstuvwxyz]. Considera il seguente esempio: java RegexDemo [a-c] clown questo esempio corrisponderà solo al carattere cche ha una corrispondenza in clown:
regex = [a-c]
input = clown
Found [c] starting at 0 and ending at 0
Espressioni regolari in Java, Parte 2 Espressioni regolari in Java, Parte 3 Espressioni regolari in Java, Parte 4 Espressioni regolari in Java, Parte 5
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION