2009-10-12 10 views
0

Je souhaite transférer un outil de traitement de texte générique, Texy!, de PHP vers Java.Java Regexp: drapeau UNGREEDY

Cet outil permet d'effectuer une correspondance unguide partout, en utilisant preg_match_all("/.../U"). Donc, je cherche une bibliothèque, qui a un drapeau UNGREEDY.

I sait Je pourrais utiliser la syntaxe .*?, mais il y a vraiment beaucoup d'expressions régulières que je devrais écraser, et les vérifier avec chaque version mise à jour.

J'ai vérifié

  • ORO - semble être abandonné
  • Jakarta Regexp - aucun soutien
  • java.util.regex - aucun support

Y at-il une telle bibliothèque ?

Merci, Ondra

Répondre

1

Je vous suggère de créer votre propre bibliothèque Java modifiée. Copiez simplement la source java.util.regex dans votre propre paquet.

La classe Sun JDK 1.6 Pattern.java offre ces drapeaux par défaut:

static final int GREEDY  = 0; 

static final int LAZY  = 1; 

static final int POSSESSIVE = 2; 

Vous remarquerez que ces drapeaux ne sont utilisés que deux ou trois fois, et il serait trivial de modifier.Prenons l'exemple suivant:

case '*': 
     ch = next(); 
     if (ch == '?') { 
      next(); 
      return new Curly(prev, 0, MAX_REPS, LAZY); 
     } else if (ch == '+') { 
      next(); 
      return new Curly(prev, 0, MAX_REPS, POSSESSIVE); 
     } 
     return new Curly(prev, 0, MAX_REPS, GREEDY); 

changer simplement la dernière ligne à utiliser le drapeau « LAZY » au lieu du drapeau GOURMANDE. Puisque vous voulez une bibliothèque regex se comporter comme celle de PHP, cela pourrait être la meilleure solution.

+0

Déjà en train de le regarder en ce moment :) –

+0

En fait, le patch pour cette RFE serait aussi simple que de remplacer le GREEDY dans le chemin de retour par défaut avec une variable créée à partir des drapeaux. Super, je vais soumettre un patch au JDK :) –

3

Mise à jour: Après avoir vérifié les documents que je trouve le drapeau LAZY, ce qui est un autre terme pour non-gourmand. Cependant, il semble seulement être disponible dans OpenJDK

p = Pattern.compile("your regex here", LAZY); 
p.matcher("string to match") 

réponse originale dépréciée Honnêtement, je ne pense pas qu'il y ait un.

Tout le point du +? et *? est de sorte que vous pouvez choisir les sections à faire avidement et celles à faire paresseusement.

Greedy est le comportement par défaut car c'est l'utilisation la plus courante de + et * dans les expressions régulières. En fait, je ne peux pas penser à un seul analyseur d'expressions rationnelles qui fasse l'inverse. Comme dans où un modificateur est utilisé pour faire quelque chose de gourmand, et le défaut est paresseux.

Je sais que ce n'est pas la réponse que vous cherchez, mais, la seule façon dont je pense que vous serez en mesure de le faire fonctionner est d'ajouter le? à vos * et +. À la hausse, vous pouvez utiliser des expressions régulières pour aider à déterminer celles qui doivent être modifiées. Ou même faire les changements pour vous si tous doivent être changés. Ou si vous pouvez pouvez décrire un modèle qui identifie ce qui doit être changé.

+0

Avoir un comportement par défaut qui ne peut pas être changé simplement parce que c'est «le plus commun [...]» ne signifie pas que le changement est une mauvaise idée. – hhafez

+0

Je ne disais pas que c'était impossible, ou même inutile. Je disais simplement cela en fonction de mon expérience dans un certain nombre de langues. Je n'ai jamais vu de changement de paresse pour une expression régulière jusqu'à ce que l'Asker mentionne preg_match_all ("/.../ U"). – EmFi

+0

Wow, quand c'est dans OpenJDK, il y a de fortes chances pour que cela devienne Sun JDK! Et, j'espère, je peux prendre l'implémentation d'OpenJDK et l'utiliser dans Sun JDK. Mais, où l'avez-vous trouvé? Ce n'est pas dans le document: http://www.jdocs.com/javase/7.b12/java/util/regex/Pattern.html (qui devrait être le doc d'OpenJDK). –

1

A propos de l'idée de vérifier et revérifier toutes les expressions régulières, êtes-vous sûr que les bibliothèques PHP et Java sont d'accord sur la syntaxe assez que vous ne pas avoir à faire de toute façon? Ce que je ferais à l'avance est de les parcourir tous et d'écrire des tests (entrée et sortie) et de s'assurer qu'ils fonctionnent de la même manière dans les deux implémentations. Ensuite, imaginez un moyen de les exécuter automatiquement et vous serez couvert pour les futures mises à jour et les incompatibilités. Vous aurez encore besoin de peaufiner les choses, mais au moins vous saurez où.

+0

Eh bien, java.util.regex devrait être compatible Perl5, sans compter les quelques fonctionnalités qui ne sont pas utilisées dans l'outil - en plus de celui-ci. Et bien sûr, j'ai demandé à l'auteur de l'original PHP de créer des tests qui certifieraient d'autres implémentations. –