Compte tenu des expressions régulières suivantes: la chaîne merci !! p> Paul p> P> alice@myprovider.com code> correspondra évidemment toutes les trois expressions régulières. Dans la demande, je développe, nous ne sommes intéressés que par le match «le plus spécifique». Dans ce cas, c'est évidemment le premier.
Malheureusement, il ne semble aucun moyen de le faire. Nous utilisons PCRE et je n'ai pas trouvé de moyen de faire cela et une recherche sur Internet n'a pas été fructueuse.
Une manière éventuelle serait de garder les expressions régulières triées sur une spécificité décroissante, puis de prendre le premier match. Bien sûr, la question suivante serait de savoir comment trier la gamme d'expressions régulières. Ce n'est pas une option pour donner la responsabilité à l'utilisateur final pour s'assurer que le tableau est trié.
J'espère donc que vous pourriez vous aider ici ... p>
4 Réponses :
Mon instinct d'intestin dit que non seulement cela est un problème dur, tant en termes de difficultés de calcul calculationnel que de difficultés de mise en œuvre, mais cela peut être insoluble de manière réaliste. Considérez les deux expressions régulières suivantes pour accepter la chaîne lequel d'entre eux est plus spécifique? P> P> alice@myprovider.com code>
Celui avec plus de constantes de caractère? Ou peut-être que vous pourriez automatiquement construire une expression régulière qui était l'intersection de ces deux. C'est-à-dire que si re (a) définit la langue L1 et REA (B) définit la langue L2, construisez une expression régulière Re (A, B) qui définit une intersection linguistique (L1, L2).
Ce qui suit est la solution à ce problème que j'ai développé sur la base du document de recherche de Donald Miner, mis en œuvre dans Python, pour les règles appliquées aux adresses MAC.
Fondamentalement, la correspondance la plus spécifique provient du modèle qui n'est pas un superset de tout autre motif correspondant. Pour un domaine problématique particulier, vous créez une série de tests (fonctions) qui comparent deux res et retournements qui sont la superset ou si elles sont orthogonales. Cela vous permet de construire un arbre de matchs. Pour une chaîne d'entrée particulière, vous traversez les motifs racines et trouvez des correspondances. Ensuite, passez à travers leurs subppatres. Si, à un moment donné, une erreur de motifs orthogonaux, une erreur est relevée. P>
Configuration strong> p> Chaque test prend 2 chaînes (A et B) et essaie de déterminer comment ils sont liés. Si le test ne peut pas déterminer la relation, aucune n'est renvoyée. P> le graphique strong> < / p> usage strong> p> une version utilisable complète est ici . p> p> Superset code> signifie
A code> est un superset de
B code>. Toutes les correspondances de
B code> correspondront à
A code>. P>
sous-ensemble code> signifie
B code> est un superset de
a code>. p>
intersect code> signifie que certaines correspondances de
A code> correspondront
b code>, mais certains ont gagné 't et quelques allumettes de
b code> ne correspondent pas
a code>. p>
disjoint code> ne signifie pas de correspondances de
code> correspondra
b code>. p>
égal code> signifie que toutes les correspondances de
A code> correspondront
b Code> et toutes les correspondances de
B code> correspondront à
a code>. p>
Poker sur le site de l'auteur J'ai trouvé ceci: Ce n'est pas grillé, alors n'allez pas l'utiliser sans l'avoir contacté en premier. Maple.cs.umbc.edu/~don/projects/ ugrad-ht / regexfind.py
Les URL spécifiées ne sont pas valides
Je ne suis pas surpris. J'ai parlé à l'auteur (il y a des années maintenant) et il a dit que c'est bien de réutiliser son travail avec ou sans attribution. Je verrai sur la modification de la réponse.
Je pense à un problème similaire pour un analyseur d'itinéraire PHP Projets. Après avoir lu les autres réponses et commentaires ici, et réfléchissez également au coût impliqué, je pourrais aller dans une autre direction tout à fait.
Une solution cependant, serait simplement de trier la liste d'expression régulière en ordre de sa longueur de chaîne. P >
Ce n'est pas parfait, mais simplement en supprimant les champs [], ce serait beaucoup plus proche. Sur le premier exemple de la question, il s'agirait de cette liste: p> à ceci, après avoir retiré le contenu de tout [] -group: p> La même chose va pour le deuxième exemple dans une autre réponse, avec les plans [] complètement retirés et triés par longueur, ceci: p> serait trié comme : P> +@myprovider.com
alice@+\.+
C'est un peu un piratage, mais cela pourrait fournir une solution pratique à cette question posée il y a près de 10 ans.
Comme indiqué par @torak, il y a des difficultés à définir ce que cela signifie pour une expression régulière de Soyez plus spécifique qu'un autre. P>
Ma suggestion est de regarder comment stables em> l'expression régulière est par rapport à une chaîne qui l'associe. Le moyen habituel d'enquêter sur la stabilité consiste à apporter des modifications mineures aux entrées et à voir si vous obtenez toujours le même résultat. P> Par exemple, la chaîne Donc, dans la recherche de la plus spécifique Regex, Nous recherchons le moins stable en ce qui concerne une chaîne qui la correspond. p> Afin de mettre en œuvre ce test de stabilité, nous devons définir comment nous choisissons une modification mineure de la chaîne qui correspond à la fuge . C'est une autre canette de vers. Nous pourrions par exemple, choisir de changer chaque caractère de la chaîne à quelque chose de hasard et de tester avec quelque chose contre la regex ou de tout nombre d'autres choix possibles. Pour la simplicité, je suggère de supprimer un caractère à la fois de la chaîne et de tester cela. P> Donc, si la chaîne qui correspond à n caractères est longue, nous avons des tests à faire. Permet de supprimer un personnage à la fois de la chaîne La regex avec le score le plus bas est le plus spécifique. Bien sûr, en général, il peut y avoir plus d'une regex avec le même score, qui reflète le fait qu'il existe des expressions régulières qui, par une manière raisonnable de mesurer la spécificité, sont aussi spécifiques que l'autre. Bien que cela puisse également donner le même score pour des expressions régulières que l'on peut facilement discuter n'est pas aussi spécifique que l'autre (si vous pouvez penser à un exemple, veuillez commenter). P> mais revenant à la question posée par @torak, lequel d'entre eux est plus spécifique: p> Nous pourrions faire valoir que la seconde est plus spécifique car elle contrainte plus de caractères et que le test ci-dessus sera d'accord avec cette vue. . P> Comme je l'ai dit, la façon dont nous choisissons de faire des modifications mineures à la chaîne correspondant à plus d'une regex est une canette de vers et la réponse que les rendements de la méthode ci-dessus peuvent dépendre de ce choix. Mais comme je l'ai dit, il s'agit d'un piratage facilement mis en œuvre - ce n'est pas rigoureux. P> et, bien sûr, la méthode rompt si la chaîne qui correspond est vide. L'utilité si le test augmentera lorsque la longueur de la chaîne augmente. Avec des cordes très courtes, il est plus probable à produire des scores égaux pour des expressions régulières qui sont clairement différentes dans leur spécificité. P> P> alice@myprovider.com code> correspondance Le regex
/alice@myprovider\.com / code>, mais si vous apportez une modification de la chaîne, elle ne correspondra pas. Donc, cette regex est très instable. Mais le regex
/.*/ code> est très stable, car vous pouvez modifier la chaîne et correspond toujours. P>
alice@foo.com code>, qui correspond à toutes les expressions régulières du tableau ci-dessous. Il y a 12 caractères, donc il y a 12 tests. Dans le tableau ci-dessous, p>
Ce n'est pas évident pour moi que le premier est
le plus spécifique code>. Quelle est votre définition de
le plus spécifique code> définir un algorithme pour cela et vous serez à mi-chemin. Mais il me semble un moyen facile de le faire (comme Flex) est que vous avez plusieurs expressions qui correspondent exactement à la première définie dans vos données.