compile()
Metoda nazywana jest zawsze w pewnym momencie; to jedyny sposób na stworzenie obiektu Pattern. Tak więc pytanie brzmi naprawdę, dlaczego miałbyś to nazwać wyraźnie ? Jednym z powodów jest to, że potrzebujesz odniesienia do obiektu Matcher, aby móc używać jego metod, takich jak group(int)
pobieranie zawartości grup przechwytywania. Jedynym sposobem na zdobycie obiektu Matcher jest użycie matcher()
metody obiektu Pattern , a jedynym sposobem na uzyskanie uchwytu obiektu Pattern jest użycie compile()
metody. Następnie jest find()
metoda, która w przeciwieństwie do matches()
klas String lub Pattern nie jest duplikowana.
Innym powodem jest unikanie ciągłego tworzenia tego samego obiektu Pattern. Za każdym razem, gdy używasz jednej z metod opartych na wyrażeniach regularnych w łańcuchu (lub matches()
metody statycznej we wzorcu), tworzy ona nowy wzorzec i nowy element dopasowujący. Więc ten fragment kodu:
for (String s : myStringList) {
if ( s.matches("\\d+") ) {
doSomething();
}
}
... jest dokładnie równoważne z tym:
for (String s : myStringList) {
if ( Pattern.compile("\\d+").matcher(s).matches() ) {
doSomething();
}
}
Oczywiście robi to dużo niepotrzebnej pracy. W rzeczywistości skompilowanie wyrażenia regularnego i utworzenie wystąpienia obiektu Pattern może z łatwością zająć więcej czasu niż wykonanie rzeczywistego dopasowania. Dlatego zwykle ma sens wyciągnięcie tego kroku z pętli. Możesz również stworzyć Matchera z wyprzedzeniem, chociaż nie są one tak drogie:
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("");
for (String s : myStringList) {
if ( m.reset(s).matches() ) {
doSomething();
}
}
Jeśli znasz wyrażenia regularne .NET, możesz się zastanawiać, czy compile()
metoda Javy jest powiązana z RegexOptions.Compiled
modyfikatorem .NET ; odpowiedź brzmi nie. Pattern.compile()
Metoda Java jest po prostu odpowiednikiem konstruktora Regex platformy .NET. Po określeniu Compiled
opcji:
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
... kompiluje wyrażenie regularne bezpośrednio do kodu bajtowego CIL, dzięki czemu może działać znacznie szybciej, ale przy znacznych kosztach przetwarzania wstępnego i wykorzystania pamięci - potraktuj to jako sterydy dla wyrażeń regularnych. Java nie ma odpowiednika; nie ma różnicy między wzorcem, który jest tworzony za kulisami, String#matches(String)
a tym, który tworzysz jawnie Pattern#compile(String)
.
(EDYCJA: Pierwotnie powiedziałem, że wszystkie obiekty .NET Regex są buforowane, co jest niepoprawne. Od czasu .NET 2.0 automatyczne buforowanie występuje tylko w przypadku metod statycznych, takich jak Regex.Matches()
bezpośrednie wywołanie konstruktora Regex. Ref )