Próbuję zrozumieć ten blok kodu. W pierwszym, czego szukamy w wyrażeniu?
Rozumiem, że jest to dowolny znak (0 lub więcej razy *), po którym następuje dowolna liczba od 0 do 9 (jeden lub więcej razy +), po której następuje dowolny znak (0 lub więcej razy *).
Po wykonaniu tej czynności wynikiem jest:
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
Czy ktoś mógłby przejść przez to ze mną?
Jakie są zalety korzystania z grup przechwytywania?
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTut3 {
public static void main(String args[]) {
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}
}
Odpowiedzi:
Problem dotyczy rodzaju kwantyfikatora. Używasz chciwego kwantyfikatora w swojej pierwszej grupie (indeks 1 - indeks 0 reprezentuje całość
Pattern
), co oznacza, że będzie on pasował jak najwięcej (a ponieważ jest to dowolny znak, dopasuje tyle znaków, ile jest w celu spełnienia warunku dla następnych grup).Krótko mówiąc, pierwsza grupa
.*
pasuje do wszystkiego, o ile następna grupa\\d+
może coś dopasować (w tym przypadku ostatnia cyfra).Zgodnie z trzecią grupą, dopasuje wszystko po ostatniej cyfrze.
Jeśli zmienisz to na niechętny kwantyfikator w swojej pierwszej grupie, otrzymasz wynik, jakiego oczekujesz, czyli część 3000 .
Zwróć uwagę na znak zapytania w pierwszej grupie.
Wynik:
Więcej informacji o Javie
Pattern
tutaj .Wreszcie, grupy przechwytywania są oddzielone nawiasami okrągłymi i zapewniają bardzo przydatny sposób używania odwołań wstecznych (między innymi), gdy już
Pattern
dopasujesz dane wejściowe.W Javie 6 do grup można się odwoływać tylko poprzez ich kolejność (uwaga na zagnieżdżone grupy i subtelną kolejność).
W Javie 7 jest to znacznie łatwiejsze, ponieważ możesz używać nazwanych grup.
źródło
named-regexp
.To jest całkowicie w porządku.
m.group(0)
) zawsze obejmuje cały obszar objęty wyrażeniem regularnym . W tym przypadku jest to cały ciąg.(.*)(\\d+)
(Pierwsza część swojej regex) obejmuje...QT300
int pierwszą grupę i0
na sekundę.(.*)
na(.*?)
.Aby uzyskać więcej informacji na temat chciwych i leniwych, odwiedź tę stronę.
źródło
Z dokumentu:
Więc przechwytuj grupę 0, wyślij całą linię.
źródło
Twoje rozumienie jest prawidłowe. Jeśli jednak przejdziemy przez:
(.*)
połknie cały sznurek;(\\d+)
był usatysfakcjonowany (dlatego0
jest przechwytywany, a nie3000
);(.*)
pochwyci resztę.Nie jestem jednak pewien, jaki był pierwotny zamiar autora.
źródło