Die compile()
Methode wird immer irgendwann aufgerufen; Dies ist die einzige Möglichkeit, ein Musterobjekt zu erstellen. Die Frage ist also wirklich, warum Sie es explizit nennen sollten . Ein Grund dafür ist, dass Sie einen Verweis auf das Matcher-Objekt benötigen, damit Sie dessen Methoden verwenden können, group(int)
um beispielsweise den Inhalt von Erfassungsgruppen abzurufen. Die einzige Möglichkeit, das Matcher-Objekt in den Griff zu bekommen, ist die matcher()
Methode des Pattern-Objekts , und die einzige Möglichkeit, das Pattern-Objekt in den Griff zu bekommen, ist die compile()
Methode. Dann gibt es die find()
Methode, die im Gegensatz zu matches()
den Klassen String oder Pattern nicht dupliziert wird.
Der andere Grund besteht darin, zu vermeiden, dass immer wieder dasselbe Musterobjekt erstellt wird. Jedes Mal, wenn Sie eine der regex-basierten Methoden in String (oder die statische matches()
Methode in Pattern) verwenden, werden ein neues Pattern und ein neuer Matcher erstellt. Also dieses Code-Snippet:
for (String s : myStringList) {
if ( s.matches("\\d+") ) {
doSomething();
}
}
... ist genau gleichbedeutend damit:
for (String s : myStringList) {
if ( Pattern.compile("\\d+").matcher(s).matches() ) {
doSomething();
}
}
Das macht natürlich viel unnötige Arbeit. Tatsächlich kann das Kompilieren des regulären Ausdrucks und das Instanziieren des Musterobjekts leicht länger dauern als das Durchführen einer tatsächlichen Übereinstimmung. Daher ist es normalerweise sinnvoll, diesen Schritt aus der Schleife zu ziehen. Sie können den Matcher auch im Voraus erstellen, obwohl er bei weitem nicht so teuer ist:
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("");
for (String s : myStringList) {
if ( m.reset(s).matches() ) {
doSomething();
}
}
Wenn Sie mit .NET-Regexen vertraut sind, fragen Sie sich möglicherweise, ob die Java- compile()
Methode mit dem .NET- RegexOptions.Compiled
Modifikator zusammenhängt. Die Antwort ist nein. Die Java- Pattern.compile()
Methode entspricht lediglich dem Regex-Konstruktor von .NET. Wenn Sie die Compiled
Option angeben :
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
... kompiliert den regulären Ausdruck direkt in CIL-Bytecode, wodurch er eine viel schnellere Leistung erbringt, jedoch zu erheblichen Kosten bei der Vorabverarbeitung und der Speichernutzung - stellen Sie sich ihn als Steroide für reguläre Ausdrücke vor. Java hat kein Äquivalent; Es gibt keinen Unterschied zwischen einem Muster, das hinter den Kulissen erstellt wurde, String#matches(String)
und einem Muster, mit dem Sie explizit erstellen Pattern#compile(String)
.
(BEARBEITEN: Ich habe ursprünglich gesagt, dass alle .NET Regex-Objekte zwischengespeichert werden, was falsch ist. Seit .NET 2.0 erfolgt das automatische Caching nur mit statischen Methoden wie Regex.Matches()
, nicht wenn Sie einen Regex-Konstruktor direkt aufrufen. Ref )