Ricerca…


introduzione

Un'espressione regolare è una sequenza speciale di caratteri che aiuta a trovare corrispondenze o trovare altre stringhe o gruppi di stringhe, utilizzando una sintassi specializzata contenuta in un modello. Java ha il supporto per l'uso regolare delle espressioni tramite il pacchetto java.util.regex . Questo argomento è quello di introdurre e aiutare gli sviluppatori a capire di più con esempi su come le espressioni regolari devono essere utilizzate in Java.

Sintassi

  • Pattern patternName = Pattern.compile (regex);
  • Matcher matcherName = patternName.matcher (textToSearch);
  • matcherName.matches () // Restituisce vero se textToSearch corrisponde esattamente all'espressione regolare
  • matcherName.find () // Cerca tra textToSearch per la prima istanza di una sottostringa che corrisponde alla regex. Le chiamate successive cercheranno il resto della stringa.
  • matcherName.group (groupNum) // Restituisce la sottostringa all'interno di un gruppo di cattura
  • matcherName.group (groupName) // Restituisce la sottostringa all'interno di un gruppo di acquisizione denominato (Java 7+)

Osservazioni

importazioni

Prima di poter utilizzare Regex è necessario aggiungere le seguenti importazioni:

import java.util.regex.Matcher
import java.util.regex.Pattern

insidie

In java, una barra rovesciata viene sfuggita con una doppia barra rovesciata, quindi una barra rovesciata nella stringa regex deve essere immessa come una doppia barra rovesciata. Se è necessario sfuggire a una doppia barra rovesciata (per abbinare una singola barra inversa con la regex, è necessario inserirla come una barra rovesciata quadrupla.

Simboli importanti spiegati

Personaggio Descrizione
* Abbina il carattere precedente o la sottoespressione 0 o più volte
+ Abbina il carattere o la sottoespressione precedente 1 o più volte
? Abbina il carattere precedente o la sottoespressione 0 o 1 volte

Ulteriori letture

L' argomento espressioni regolari contiene ulteriori informazioni sulle espressioni regolari.

Utilizzo dei gruppi di cattura

Se è necessario estrarre una parte di stringa dalla stringa di input, possiamo usare i gruppi di cattura di regex.

Per questo esempio, inizieremo con un semplice numero di telefono regex:

\d{3}-\d{3}-\d{4}

Se le parentesi sono aggiunte alla regex, ciascuna serie di parentesi viene considerata un gruppo di cattura . In questo caso, stiamo usando quelli che sono chiamati gruppi di cattura numerati:

(\d{3})-(\d{3})-(\d{4})
^-----^ ^-----^ ^-----^
Group 1 Group 2 Group 3

Prima di poterlo utilizzare in Java, non dobbiamo dimenticare di seguire le regole di Stringhe, sfuggire alle barre inverse, con il seguente schema:

"(\\d{3})-(\\d{3})-(\\d{4})"

Per prima cosa dobbiamo compilare il modello regex per creare un Pattern e quindi abbiamo bisogno di un Matcher per abbinare la nostra stringa di input con il pattern:

Pattern phonePattern = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher("abcd800-555-1234wxyz");

Successivamente, il Matcher deve trovare la prima sottosequenza che corrisponde alla regex:

phoneMatcher.find();

Ora, usando il metodo di gruppo, possiamo estrarre i dati dalla stringa:

String number = phoneMatcher.group(0); //"800-555-1234" (Group 0 is everything the regex matched)
String aCode = phoneMatcher.group(1); //"800"
String threeDigit = phoneMatcher.group(2); //"555"
String fourDigit = phoneMatcher.group(3); //"1234"

Nota: Matcher.group() può essere utilizzato al posto di Matcher.group(0) .

Java SE 7

Java 7 ha introdotto i gruppi di acquisizione denominati. I gruppi di cattura con nome funzionano allo stesso modo dei gruppi di cattura numerati (ma con un nome anziché un numero), sebbene vi siano lievi modifiche alla sintassi. L'utilizzo dei gruppi di acquisizione con nome migliora la leggibilità.

Possiamo modificare il codice precedente per utilizzare i gruppi denominati:

(?<AreaCode>\d{3})-(\d{3})-(\d{4})
^----------------^ ^-----^ ^-----^
AreaCode           Group 2 Group 3

Per ottenere il contenuto di "AreaCode", possiamo invece utilizzare:

String aCode = phoneMatcher.group("AreaCode"); //"800"

Usare espressioni regolari con comportamento personalizzato compilando Pattern con flag

Un Pattern può essere compilato con flag, se la regex è usata come String letterale, usa i modificatori in linea:

Pattern pattern = Pattern.compile("foo.", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
pattern.matcher("FOO\n").matches(); // Is true.

/* Had the regex not been compiled case insensitively and singlelined,
 * it would fail because FOO does not match /foo/ and \n (newline)
 * does not match /./.
 */

Pattern anotherPattern = Pattern.compile("(?si)foo");
anotherPattern.matcher("FOO\n").matches(); // Is true.

"foOt".replaceAll("(?si)foo", "ca"); // Returns "cat".

Personaggi di fuga

Generalmente

Per usare caratteri specifici dell'espressione regolare ( ?+| Ecc.) Nel loro significato letterale, devono essere sfuggiti. Nell'espressione regolare comune ciò è fatto da una barra rovesciata \ . Tuttavia, poiché ha un significato speciale in Java Strings, devi usare una doppia barra rovesciata \\ .

Questi due esempi non funzioneranno:

"???".replaceAll ("?", "!"); //java.util.regex.PatternSyntaxException
"???".replaceAll ("\?", "!"); //Invalid escape sequence

Questo esempio funziona

"???".replaceAll ("\\?", "!"); //"!!!"

Divisione di una stringa delimitata da un tubo

Questo non restituisce il risultato atteso:

"a|b".split ("|"); // [a, |, b]

Ciò restituisce il risultato previsto:

"a|b".split ("\\|"); // [a, b]

Escaping backslash \

Questo darà un errore:

"\\".matches("\\"); // PatternSyntaxException
"\\".matches("\\\"); // Syntax Error

Questo funziona:

"\\".matches("\\\\"); // true

Corrispondenza con una regex letterale.

Se è necessario abbinare i caratteri che fanno parte della sintassi delle espressioni regolari, è possibile contrassegnare tutto o parte del modello come un regex letterale.

\Q segna l'inizio della regex letterale. \E segna la fine della regex letterale.

// the following throws a PatternSyntaxException because of the un-closed bracket
"[123".matches("[123");

// wrapping the bracket in \Q and \E allows the pattern to match as you would expect.
"[123".matches("\\Q[\\E123"); // returns true

Un modo più semplice per farlo senza dover ricordare le sequenze di escape \Q e \E è usare Pattern.quote()

"[123".matches(Pattern.quote("[") + "123"); // returns true

Non corrisponde a una determinata stringa

Per abbinare qualcosa che non contiene una determinata stringa, si può usare lookahead negativo:

Sintassi Regex: (?!string-to-not-match)

Esempio:

//not matching "popcorn"
String regexString = "^(?!popcorn).*$";
System.out.println("[popcorn] " + ("popcorn".matches(regexString) ? "matched!" : "nope!"));
System.out.println("[unicorn] " + ("unicorn".matches(regexString) ? "matched!" : "nope!"));

Produzione:

[popcorn] nope!
[unicorn] matched!

Abbinare una barra rovesciata

Se vuoi abbinare una barra rovesciata nella tua espressione regolare, dovrai fuggire.

Il backslash è un carattere di escape nelle espressioni regolari. Puoi usare '\\' per fare riferimento a una singola barra rovesciata in un'espressione regolare.

Tuttavia, il backslash è anche un carattere di escape nelle stringhe letterali Java. Per fare un'espressione regolare da una stringa letterale, devi sfuggire a ciascuna delle sue barre retroverse. In una stringa letterale '\\\\' può essere usato per creare un'espressione regolare con '\\', che a sua volta può corrispondere a '\'.

Ad esempio, considera l'abbinamento di stringhe come "C: \ dir \ myfile.txt". Un'espressione regolare ([A-Za-z]):\\(.*) Corrisponderà e fornirà la lettera di unità come gruppo di cattura. Notare il backslash raddoppiato.

Per esprimere quel modello in una stringa letterale Java, è necessario che tutti i backslash nell'espressione regolare debbano essere sottoposti a escape.

    String path = "C:\\dir\\myfile.txt";
    System.out.println( "Local path: " + path ); // "C:\dir\myfile.txt"
    
    String regex = "([A-Za-z]):\\\\.*"; // Four to match one
    System.out.println("Regex:      " + regex ); // "([A-Za-z]):\\(.*)"
    
    Pattern pattern = Pattern.compile( regex );
    Matcher matcher = pattern.matcher( path );
    if ( matcher.matches()) {
        System.out.println( "This path is on drive " + matcher.group( 1 ) + ":.");
        // This path is on drive C:.
    }

Se vuoi abbinare due backslash, ti troverai usando otto in una stringa letterale, per rappresentare quattro nell'espressione regolare, per abbinarne due.

    String path = "\\\\myhost\\share\\myfile.txt";
    System.out.println( "UNC path: " + path ); // \\myhost\share\myfile.txt"
    
    String regex = "\\\\\\\\(.+?)\\\\(.*)"; // Eight to match two
    System.out.println("Regex:    " + regex ); // \\\\(.+?)\\(.*) 
    
    Pattern pattern = Pattern.compile( regex );
    Matcher matcher = pattern.matcher( path );
    
    if ( matcher.matches()) {
        System.out.println( "This path is on host '" + matcher.group( 1 ) + "'.");
        // This path is on host 'myhost'.
    }


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow