11
votes

Java: Comment puis-je déterminer pourquoi un match de modèle d'expression régulier échoue?

J'utilise une expression régulière pour correspondre à une correspondance de motif, mais je veux aussi savoir quand il échoue.

Par exemple, disons que j'ai un modèle de "n {1,3} y". Je le fais correspond à la chaîne "Nnnny". J'aimerais savoir que cela a échoué parce qu'il y avait trop de NS. Ou si je le fais correspond à la chaîne "xnny", je voudrais savoir qu'il a échoué parce qu'un caractère non valide "x" était dans la chaîne.

En regardant l'API d'expression régulière Java (Java.Util.regex), des informations supplémentaires ne semblent être disponibles que dans la classe de correspondance lorsque la correspondance réussit.

Y a-t-il un moyen de résoudre ce problème? Ou est une expression régulière même une option dans ce scénario?


4 commentaires

Je ne connais aucun moteur de regex qui fournit cette information lors de la correspondance.


Ce n'est pas possible. Une chaîne peut ne pas correspondre à de nombreuses raisons différentes. Et, de toute façon, aucun moteur ne le fait.


C'est une sorte de question ouverte de pourquoi quelque chose ne correspondait pas. Vous pouvez définir des expressions régulières qui correspondent à des situations spécifiques qui sont "non correspondantes" mais une réponse générale n'est pas possible. Pourquoi "Abcdef" ne correspond-il pas? C'est la mauvaise longueur, il n'a pas de caractères «n», il ne se termine pas dans Y, il est minuscule, etc.


Une regex est conçue pour trouver rapidement et efficacement des motifs. Votre exigence n'a rien à voir avec la recherche de matchs, mais plus avec l'analyse des intrants. Vous pouvez résoudre celui-ci avec un motif Xustom ou un ensemble de regex, pour chaque cas d'erreur séparé.


4 Réponses :


1
votes

Ce que vous demandez nécessiterait que l'analyseur détermine une chaîne à proximité qui correspond à votre expression. Il s'agit d'un problème non trivial qui fonctionnerait probablement dans une période exponentielle (par exemple, recherchez toutes les chaînes possibles de longueur similaire pour trouver une correspondance.)

Donc, en bref, non.


0 commentaires

9
votes

Je suppose que vous devriez utiliser un analyseur, plutôt que de simples expressions régulières.

Les expressions régulières sont bonnes fournissant des allumettes pour la chaîne, mais pas tout à fait pour fournir des non-matchs, sans parler d'expliquer pourquoi un match a échoué.


2 commentaires

Merci, je pensais avoir besoin d'un parser. Je suppose que cela le confirme.


-1 Je pense que ce n'est pas une réponse, mais un bon commentaire. Les expressions régulières vont bien, il vous suffit de comprendre ce que la classe de correspondance peut vous donner.



2
votes

Cela peut fonctionner mais je ne sais pas si c'est ainsi que vous en avez besoin.

Lorsque vous utilisez correspondant , il échoue si la séquence entière ne correspond pas, mais vous pouvez toujours utiliser trouver pour voir si le reste de la séquence contenait le motif. Et ainsi comprendre pourquoi il a échoué: xxx

sortie: xxx

dans la première sortie: n [nnny ] vous pouvez en dire là où trop de N, dans la seconde: x [NNY] Il y avait un X présent.

Voici une autre sortie < Pré> xxx

Le motif est là, mais toute l'expression ne correspondait pas.

C'est un peu difficile de comprendre comment trouver, des allumettes et de la vue à la recherche de la doc (au moins cela est arrivé à moi) mais j'espère que cet exemple vous aide à comprendre.

correspondance est comme / ^ votrepatternHere $ /

lookat est comme / ^ votrepatternhere /

Trouver est comme / votrepatternhere /

J'espère que cela aide.


0 commentaires

0
votes

Pour des expressions simples comme "N {1,3} y", vous trouverez la solution sans outil vous-même. Mais pour des expressions plus compliquées, mon expérience suggère:

  • fendez des expressions plus grandes en plus petites et les tester de manière indépendante.
  • Depuis que vous aimez avoir un retour rapide, vous pouvez utiliser une coque interactive comme BeanShell, pour tester rapidement des cordes et des motifs rapidement, sans grand compilation, ni gros plan, statique, principale (bla ...) et ainsi de suite. Ou essayez scala pour cette tâche. SED est un autre outil puissant pour utiliser des expressions régulières, mais il existe des différences subtiles dans la syntaxe, ce qui peut introduire de nouvelles erreurs.
  • Souvent, le masquage est un problème. Étant donné que les backslashes ont besoin d'une autre barre oblique inverse, il peut s'agir d'un avantage de lire l'expression d'un jtextfield, où vous n'avez pas besoin de tant de masquage.
  • Écrivez un petit cadre de test pour vos expressions, où vous pouvez facilement mettre vos expressions dans, les chaînes de test, dans, peut-être produire des données de test automatiques et obtenir des commentaires visuels.

0 commentaires