7
votes

Découvrez quel groupe correspond à Java Regex sans recherche linéaire?

J'ai assemblé de manière programmée énorme regex, comme celui-ci xxx

chaque sous-modèle est dans son groupe de capture. Lorsque je reçois une correspondance, comment puis-je déterminer quel groupe correspond sans tester linéairement chaque groupe pour le renvoyer une chaîne non nulle?


2 commentaires

Voulez-vous trouver quels matchs de groupe ou quels sont les contenus du groupe?


Je ne suis pas au courant d'un système de regex qui fait ce que vous demandez et je suis sûr que celui de Core Java fait son système de manière linéairement. Voir @thomas 'Post pour de meilleurs détails.


5 Réponses :


4
votes

Si votre regex est généré par programmation, pourquoi ne pas générer de manière programmatique n des regex distincts et tester chacun d'eux à son tour? À moins qu'ils partagent un préfixe commune et que le moteur Java Regex est intelligent, toutes les alternatives sont testées de toute façon.

MISE À JOUR: Je viens de regarder à travers la source Java Sun, en particulier, java.util.regex.pattern $ suck.Match (), et cela fait simplement une recherche linéaire sur toutes les alternatives, essayant chacun à son tour. Les autres endroits où la branche est utilisée ne suggère aucune optimisation des préfixes courants.


1 commentaires

Oui, ils pourraient partager des préfixes, etc.



0
votes

rompre votre regex en trois: xxx

L'alternative est la suivante: xxx


2 commentaires

Je ne veux pas faire une recherche linéaire. Je demande si je peux obtenir des fonctionnalités de cette méthode de méthode inexistante.getmatchedGroupIndex () qui me dise magiquement quel groupe est assorti sans moi sans que je pataugeant chaque groupe pour le tester.


J'ai ajouté la méthode getMatchedGroupIndex (), mais sous les couvertures, elle utilisera toujours une boucle pour itérale à travers le contenu du groupe.



0
votes

Je ne pense pas que vous puissiez contourner la recherche linéaire, mais vous pouvez le rendre beaucoup plus efficace en utilisant start (int) code> au lieu de groupe (int) code >.

static int getMatchedGroupIndex(Matcher m)
{ 
  int index = -1;
  for (int i = 1, n = m.groupCount(); i <= n; i++)
  {
    if ( (index = m.start(i)) != -1 )
    {
      break;
    }
  }
  return index;
}


0 commentaires

0
votes

des différents commentaires, il semble que la réponse simple soit "non", et que l'utilisation des regex distinctes est une meilleure idée. Pour améliorer cette approche, vous devrez peut-être comprendre les préfixes de modèle commun lorsque vous les générerez, ou utilisez votre propre moteur de correspondance de modèles de rééglementation (ou autre). Mais avant d'aller à tous ces efforts, vous devez être sûr qu'il s'agit d'un goulot d'étranglement important dans votre système. En d'autres termes, il y a de référence et voyez si la performance est acceptable pour les données d'entrée réalistes, et sinon le profil pour voir où sont les véritables goulots d'étranglement.


0 commentaires

1
votes

Vous pouvez utiliser des groupes non capturants, au lieu de:

(a) | (b) | (c) | ...

Remplacer par

((?: a) | (?: b) | (?: c))

Les groupes non capturants (? :) ne seront pas inclus dans le nombre de groupes, mais le résultat de la branche sera capturé dans le groupe externe ().


0 commentaires