119 votes

java.util.regex - importance de Pattern.compile ()?

Quelle est l’importance de la méthode Pattern.compile() ?
Pourquoi dois-je compiler la chaîne regex avant d’obtenir l’objet Matcher ?

par exemple :

 String regex = "((\\S+)\\s*some\\s*";

Pattern pattern = Pattern.compile(regex); // why i need to compile
Matcher matcher = pattern.matcher(text); //
 

147voto

Alan Moore Points 39365

L' compile() méthode est toujours appelé à un certain point; c'est la seule façon de créer un Modèle objet. Donc, la question est vraiment, pourquoi devriez-vous appeler explicitement? Une des raisons est que vous avez besoin d'une référence à la Correspondance de l'objet de sorte que vous pouvez utiliser ses méthodes, comme group(int) pour récupérer le contenu de la capture de groupes. La seule façon d'obtenir ahold de la Correspondance de l'objet est à travers le Modèle de l'objet matcher() méthode, et la seule façon de m'approprier le Modèle objet est par le biais de l' compile() méthode. Puis il y a l' find() méthode qui, à la différence matches(), n'est pas reproduit dans la Chaîne ou le Modèle de classes.

L'autre raison est d'éviter de créer le même Modèle objet. Chaque fois que vous utilisez l'un des regex alimenté méthodes de Chaîne (ou la statique matches() méthode dans le Modèle), il crée un nouveau Modèle et une nouvelle Matcher. Donc ce bout de code:

for (String s : myStringList) {
    if ( s.matches("\\d+") ) {
        doSomething();
    }
}

...est exactement équivalent à ceci:

for (String s : myStringList) {
    if ( Pattern.compile("\\d+").matcher(s).matches() ) {
        doSomething();
    }
}

Évidemment, ça fait beaucoup de travail inutile. En fait, il peut facilement prendre plus de temps pour compiler les regex et instancier le Modèle de l'objet, qu'il n'en faut pour effectuer une véritable match. De sorte qu'il est souvent logique à tirer de cette étape de la boucle. Vous pouvez créer le Comparateur de venir de temps en tant que bien, mais ils ne sont pas près si cher:

Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("");
for (String s : myStringList) {
    if ( m.reset(s).matches() ) {
        doSomething();
    }
}

Si vous êtes familier avec .NET regexes, vous demandez peut-être si Java est compile() méthode est de .NET RegexOptions.Compiled modificateur; la réponse est non. Java Pattern.compile() méthode est simplement l'équivalent .NET de la Regex constructeur. Lorsque vous spécifiez l' Compiled option:

Regex r = new Regex(@"\d+", RegexOptions.Compiled); 

...il compile les regex directement à CIL de byte code, lui permettant de réaliser beaucoup plus rapidement, mais à un coût important dans le traitement et l'utilisation de la mémoire--penser que les stéroïdes pour les regexes. Java n'a pas d'équivalent; il n'y a pas de différence entre un Patron qui a créé les coulisses en String#matches(String) et celui que vous créez explicitement Pattern#compile(String).

(EDIT: j'ai d'abord dit que tous les .NET Regex objets sont mis en cache, ce qui est incorrect. Depuis .NET 2.0, la mise en cache automatique se produit uniquement avec des méthodes statiques comme Regex.Matches(), pas lorsque vous appelez une Regex constructeur directement. réf)

40voto

Thomas Jung Points 17692

Compile analyse l'expression régulière et crée une représentation en mémoire . Les frais généraux à compiler sont importants comparés à une correspondance. Si vous utilisez un motif à plusieurs reprises, vous obtiendrez des performances pour mettre en cache le motif compilé.

17voto

jjnguy Points 62123

Lorsque vous compilez l' Pattern Java fait un peu de calcul pour vous permettre de trouver des matchs en Strings plus rapide. (Construit une représentation en mémoire de la regex)

Si vous envisagez de réutiliser l' Pattern plusieurs fois, vous verrez une grande augmentation de la performance sur la création d'un nouveau Pattern tous les temps.

Dans le cas de seulement à l'aide du Modèle une fois, la compilation étape semble juste comme un supplément de ligne de code, mais, en fait, il peut être très utile dans le cas général.

0voto

DragonBorn Points 1874

La pré-compilation de la regex augmente la vitesse. Réutiliser le Matcher vous donne une autre légère accélération. Si la méthode est appelée fréquemment et qu'elle est appelée dans une boucle, la performance globale augmentera certainement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X