Zoeken…


Invoering

Een reguliere expressie is een speciale reeks tekens die helpt bij het matchen of vinden van andere reeksen of reeksen reeksen, met behulp van een gespecialiseerde syntaxis in een patroon. Java biedt ondersteuning voor het gebruik van reguliere expressies via het pakket java.util.regex . Dit onderwerp introduceert en helpt ontwikkelaars meer te begrijpen met voorbeelden over hoe reguliere expressies moeten worden gebruikt in Java.

Syntaxis

  • Patroon patternName = Pattern.compile (regex);
  • Matcher matcherName = patternName.matcher (textToSearch);
  • matcherName.matches () // Retourneert true als de textToSearch exact overeenkomt met de regex
  • matcherName.find () // Zoekt via textToSearch naar het eerste exemplaar van een substring die overeenkomt met de regex. Volgende aanroepen zoeken de rest van de string.
  • matcherName.group (groupNum) // Retourneert de substring binnen een vastleggroep
  • matcherName.group (groupName) // Retourneert de substring binnen een benoemde vastleggroep (Java 7+)

Opmerkingen

invoer

U moet de volgende invoer toevoegen voordat u Regex kunt gebruiken:

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

valkuilen

In Java wordt een backslash ontsnapt met een dubbele backslash, dus een backslash in de regex-string moet worden ingevoerd als een dubbele backslash. Als u moet ontsnappen aan een dubbele backslash (om een enkele backslash te matchen met de regex, moet u deze invoeren als een viervoudige backslash.

Belangrijke symbolen uitgelegd

Karakter Beschrijving
* Overeenkomen met het voorgaande teken of subexpressie 0 of meer keer
+ Overeenkomen met het voorgaande teken of subexpressie 1 of meer keer
? Overeenkomen met het voorgaande teken of subexpressie 0 of 1 keer

Verder lezen

Het regex-onderwerp bevat meer informatie over reguliere expressies.

Capture groepen gebruiken

Als u nodig hebt om een deel van de string te extraheren uit de input string, kunnen we capture groepen van reguliere expressies gebruiken.

In dit voorbeeld beginnen we met een eenvoudige telefoonnummerregex:

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

Als haakjes aan de regex worden toegevoegd, wordt elke set haakjes als een vastleggroep beschouwd. In dit geval gebruiken we zogenaamde genummerde opnamegroepen:

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

Voordat we het in Java kunnen gebruiken, moeten we niet vergeten de regels van Strings te volgen en aan de backslashes te ontsnappen, wat resulteert in het volgende patroon:

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

We moeten eerst de reguliere expressie patroon samen te stellen om een make Pattern en dan moeten we een Matcher om onze input string met het patroon overeenkomen:

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

Vervolgens moet de Matcher de eerste deelreeks vinden die overeenkomt met de regex:

phoneMatcher.find();

Nu kunnen we met de groepsmethode de gegevens uit de tekenreeks extraheren:

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"

Opmerking: Matcher.group() kan worden gebruikt in plaats van Matcher.group(0) .

Java SE 7

Java 7 introduceerde benoemde capture-groepen. Benoemde opnamegroepen werken hetzelfde als genummerde opnamegroepen (maar met een naam in plaats van een nummer), hoewel er kleine syntaxiswijzigingen zijn. Het gebruik van benoemde vastleggroepen verbetert de leesbaarheid.

We kunnen de bovenstaande code wijzigen om benoemde groepen te gebruiken:

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

Om de inhoud van "AreaCode" te krijgen, kunnen we in plaats daarvan gebruiken:

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

Regex gebruiken met aangepast gedrag door het patroon te compileren met vlaggen

Een Pattern kan worden gecompileerd met vlaggen. Als de regex wordt gebruikt als een letterlijke String , gebruik dan inline modifiers:

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".

Escape-personages

Over het algemeen

Als u reguliere expressie-specifieke tekens ( ?+| Enz.) In hun letterlijke betekenis wilt gebruiken, moet u ze laten ontsnappen. In gewone reguliere expressie wordt dit gedaan door een backslash \ . Omdat het echter een speciale betekenis heeft in Java Strings, moet u een dubbele backslash gebruiken \\ .

Deze twee voorbeelden zullen niet werken:

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

Dit voorbeeld werkt

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

Een door pijp gescheiden string splitsen

Dit levert niet het verwachte resultaat op:

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

Dit levert het verwachte resultaat op:

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

Ontsnappen aan backslash \

Dit geeft een foutmelding:

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

Dit werkt:

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

Overeenkomend met een regex letterlijk.

Als u tekens moet matchen die deel uitmaken van de syntaxis van de reguliere expressie, kunt u het patroon geheel of gedeeltelijk als een letterlijk regex markeren.

\Q markeert het begin van de letterlijke regex. \E markeert het einde van de regex letterlijk.

// 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

Een eenvoudigere manier om dit te doen zonder de Escape-volgorde \Q en \E te hoeven onthouden, is om Pattern.quote()

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

Komt niet overeen met een gegeven string

Om iets dat niet een gegeven string bevat overeenkomen, kan men gebruik maken van negatieve vooruitkijken:

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

Voorbeeld:

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

Output:

[popcorn] nope!
[unicorn] matched!

Overeenkomen met een backslash

Als je een backslash in je reguliere expressie wilt matchen, moet je eraan ontsnappen.

Backslash is een escape-personage in reguliere expressies. U kunt '\\' gebruiken om naar een enkele backslash in een reguliere expressie te verwijzen.

Backslash is echter ook een ontsnappingskarakter in letterlijke tekenreeksen van Java. Om een reguliere uitdrukking van een letterlijke tekenreeks te maken, moet je aan elk van de backslashes ontsnappen. In een string kan letterlijk '\\\\' worden gebruikt om een reguliere expressie met '\\' te maken, die op zijn beurt kan overeenkomen met '\'.

Overweeg bijvoorbeeld om overeenkomende tekenreeksen zoals "C: \ dir \ myfile.txt" te zoeken. Een reguliere expressie ([A-Za-z]):\\(.*) Komt overeen en geeft de stationsletter als een vastleggroep. Let op de dubbele backslash.

Om dat patroon uit te drukken in een letterlijke Java-string, moet elk van de backslashes in de reguliere expressie worden ontsnapt.

    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:.
    }

Als je twee backslashes wilt matchen, merk je dat je acht gebruikt in een letterlijke string, om vier in de reguliere expressie te vertegenwoordigen, om twee te matchen.

    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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow