Sök…


Introduktion

Ett vanligt uttryck är en speciell sekvens av tecken som hjälper till att matcha eller hitta andra strängar eller uppsättningar av strängar, med hjälp av en specialiserad syntax som hålls i ett mönster. Java har stöd för regelbunden java.util.regex paketet java.util.regex . Detta ämne är att introducera och hjälpa utvecklare förstå mer med exempel på hur Regular Expressions måste användas i Java.

Syntax

  • MönstermönsterName = Mönster.compile (regex);
  • Matcher matcherName = patternName.matcher (textToSearch);
  • matcherName.matches () // Returnerar sant om textenToSearch exakt matchar regexet
  • matcherName.find () // Söker i textToSearch för första instansen av en substring som matchar regexet. Efterföljande samtal söker återstoden av strängen.
  • matcherName.group (groupNum) // Returnerar substrängen inuti en fångargrupp
  • matcherName.group (groupName) // Returnerar substrängen inuti en namngiven fångstgrupp (Java 7+)

Anmärkningar

import

Du måste lägga till följande import innan du kan använda Regex:

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

Fallgropar gropar~~POS=HEADCOMP

I java släpps ett backslash med ett dubbel backslash, så ett backslash i regexsträngen ska matas in som ett dubbel backslash. Om du behöver undgå ett dubbelt backslash (för att matcha ett enda backslash med regexen måste du mata in det som en fyrdubblad backslash.

Viktiga förklarade symboler

Karaktär Beskrivning
* Matcha föregående tecken eller subexpression 0 eller flera gånger
+ Matcha föregående karaktär eller subexpression en eller flera gånger
? Matcha föregående karaktär eller subexpression 0 eller 1 gånger

Vidare läsning

Regex-ämnet innehåller mer information om reguljära uttryck.

Använda fångstgrupper

Om du behöver extrahera en del av strängen från inmatningssträngen kan vi använda fångstgrupper av regex.

I det här exemplet börjar vi med ett enkelt telefonnummerregex:

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

Om parenteser läggs till i regexet betraktas varje uppsättning parenteser som en fångargrupp . I det här fallet använder vi vad som kallas numrerade fångstgrupper:

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

Innan vi kan använda det i Java, får vi inte glömma att följa strängareglerna, undvika backstreck, vilket resulterar i följande mönster:

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

Vi måste först kompilera regex-mönstret för att skapa ett Pattern och sedan behöver vi en Matcher att matcha vår inmatningssträng med mönstret:

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

Därefter måste Matcher hitta den första senare som matchar regexet:

phoneMatcher.find();

Nu kan vi använda gruppmetoden extrahera data från strängen:

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"

Obs: Matcher.group() kan användas i stället för Matcher.group(0) .

Java SE 7

Java 7 introducerade namngivna capture-grupper. Namngivna fångstgrupper fungerar på samma sätt som numrerade fångstgrupper (men med ett namn istället för ett nummer), även om det är små syntaxförändringar. Att använda namngivna fångstgrupper förbättrar läsbarheten.

Vi kan ändra koden ovan för att använda namngivna grupper:

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

För att få innehållet i "AreaCode" kan vi istället använda:

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

Använda regex med anpassat beteende genom att sammanställa mönstret med flaggor

Ett Pattern kan sammanställas med flaggor, om regex används som en bokstavlig String , använd inline modifierare:

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 karaktärer

Allmänt

För att använda vanliga uttryckspecifika tecken ( ?+| Etc.) i deras bokstavliga betydelse måste de undkomma. I vanligt regelbundet uttryck görs detta med ett motstopp \ . Men eftersom det har en speciell betydelse i Java-strängar, måste du använda ett dubbel backslash \\ .

Dessa två exempel fungerar inte:

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

Detta exempel fungerar

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

Dela en rörbegränsad sträng

Detta ger inte det förväntade resultatet:

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

Detta ger det förväntade resultatet:

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

Rymmer motslags \

Detta kommer att ge ett fel:

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

Det här fungerar:

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

Matchar med en regex literal.

Om du behöver matcha tecken som är en del av det vanliga uttryckssyntaxen kan du markera hela eller delar av mönstret som en regex letteral.

\Q markerar början på regex literal. \E markerar slutet på regex letteral.

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

Ett enklare sätt att göra det utan att behöva komma ihåg \Q och \E flygsekvenserna är att använda Pattern.quote()

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

Matchar inte en given sträng

För att matcha något som inte innehåller en given sträng kan man använda negativ lookahead:

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

Exempel:

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

Produktion:

[popcorn] nope!
[unicorn] matched!

Matchar ett motreaktion

Om du vill matcha ett motstreck i ditt vanliga uttryck måste du undgå det.

Backslash är ett flyktecken i vanliga uttryck. Du kan använda '\\' för att hänvisa till ett enda snedstreck i ett vanligt uttryck.

Men backslash är också ett flyktecken i Java-bokstavliga strängar. För att få ett regelbundet uttryck från en bokstavlig sträng måste du undgå var och en av dess bakslag. I en sträng kan bokstavligen '\\\\' användas för att skapa ett regelbundet uttryck med '\\', som i sin tur kan matcha '\'.

Överväga till exempel matchning av strängar som "C: \ dir \ myfile.txt". Ett regelbundet uttryck ([A-Za-z]):\\(.*) Kommer att matcha och tillhandahålla enhetsbokstaven som en bildgrupp. Observera det fördubblade backslashet.

För att uttrycka det mönstret i en bokstav i en Java-sträng måste vart och ett av backstegen i det reguljära uttrycket undkommas.

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

Om du vill matcha två motstreck, hittar du dig själv med åtta i en bokstavlig sträng, för att representera fyra i det vanliga uttrycket, för att matcha två.

    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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow