Il compile()
metodo viene sempre chiamato a un certo punto; è l'unico modo per creare un oggetto Pattern. Quindi la domanda è davvero, perché dovresti chiamarla esplicitamente ? Uno dei motivi è che è necessario un riferimento all'oggetto Matcher in modo da poter utilizzare i suoi metodi, ad esempio group(int)
per recuperare il contenuto dei gruppi di acquisizione. L'unico modo per ottenere l'oggetto Matcher è tramite il matcher()
metodo dell'oggetto Pattern e l'unico modo per ottenere l'oggetto Pattern è attraverso il compile()
metodo. Poi c'è il find()
metodo che, a differenza matches()
, non è duplicato nelle classi String o Pattern.
L'altro motivo è evitare di creare continuamente lo stesso oggetto Pattern. Ogni volta che usi uno dei metodi basati su espressioni regolari in String (o il matches()
metodo statico in Pattern), crea un nuovo Pattern e un nuovo Matcher. Quindi questo snippet di codice:
for (String s : myStringList) {
if ( s.matches("\\d+") ) {
doSomething();
}
}
... è esattamente equivalente a questo:
for (String s : myStringList) {
if ( Pattern.compile("\\d+").matcher(s).matches() ) {
doSomething();
}
}
Ovviamente, sta facendo un sacco di lavoro non necessario. In effetti, può facilmente richiedere più tempo per compilare la regex e istanziare l'oggetto Pattern, piuttosto che per eseguire una corrispondenza effettiva. Quindi di solito ha senso tirare quel passo fuori dal giro. Puoi anche creare il Matcher in anticipo, anche se non sono così costosi:
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("");
for (String s : myStringList) {
if ( m.reset(s).matches() ) {
doSomething();
}
}
Se hai familiarità con le regex .NET, potresti chiederti se il compile()
metodo di Java è correlato al RegexOptions.Compiled
modificatore di .NET ; la risposta è no. Il Pattern.compile()
metodo di Java è semplicemente equivalente al costruttore Regex di .NET. Quando specifichi l' Compiled
opzione:
Regex r = new Regex(@"\d+", RegexOptions.Compiled);
... compila la regex direttamente in codice byte CIL, permettendogli di eseguire molto più velocemente, ma a un costo significativo nell'elaborazione iniziale e nell'uso della memoria: pensala come steroidi per le regex. Java non ha equivalenti; non c'è differenza tra un Pattern creato dietro le quinte da String#matches(String)
e uno con cui crei esplicitamente Pattern#compile(String)
.
(EDIT: originariamente ho detto che tutti gli oggetti .NET Regex sono memorizzati nella cache, il che non è corretto. Dal momento che .NET 2.0, la memorizzazione automatica nella cache si verifica solo con metodi statici come Regex.Matches()
, non quando chiami direttamente un costruttore Regex. Ref )