Java Language
Vanliga uttryck
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 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'.
}