Disons que j'ai la chaîne suivante:
var badStr = "abcabcabc123";
Je veux écrire un modèle Regex pour qu'il renvoie trois (3) correspondances, dont la valeur de chacune est "abc". Cependant, si la chaîne s'écarte du motif répété "abc", je ne veux pas renvoyer AUCUNE correspondance.
De plus, je ne sais pas s'il y aura toujours 3 répétitions (il y a peut être n'importe quel nombre de répétitions).
Par exemple, la chaîne suivante devrait échouer et ne devrait pas avoir de correspondance:
var goodStr = "abcabcabc";
Quel modèle dois-je utiliser pour renvoyer 3 correspondances dans goodStr , mais 0 correspondance dans badStr?
En d'autres termes, la somme des dernières L'index et la longueur de la correspondance doivent être égaux à la longueur totale de la chaîne d'objet.
J'essaie de ne pas utiliser de captures / références arrière dans ce scénario également.
EDIT:
Le motif ^ (?: abc) + $ ne suffit pas car il ne renvoie qu'une seule correspondance.
Le motif ^ abcabcabc $ ne suffit pas car il suppose qu'il n'y aura que 3 répétitions de "abc", et je ne sais pas combien de répétitions il y aura dans mon scénario. De plus, il ne renvoie qu'une seule correspondance.
Avec l'aide d'Aaron et d'Anubhava, nous avons créé ce modèle qui fonctionne pour mon scénario:
\ Gabc (? = (?: abc) * $)
3 Réponses :
Vous devriez pouvoir utiliser ce qui suit en C #:
(?<=^(?:abc)*)abc(?=(?:abc)*$)
Cela correspond aux occurrences de abc à partir desquelles vous pouvez atteindre à la fois le début et le fin de la chaîne en utilisant uniquement d'autres répétitions de abc . Cela repose sur la capacité d'utiliser des lookbehinds à largeur variable, ce qui est assez rare mais que le moteur d'expression régulière de C # implémente.
J'ai pu le tester sur http://regexstorm.net/tester où il renvoie 3 correspondances pour abcabcabc mais 0 pour abcabcabc123 .
cela fonctionne très bien. Merci. Cependant, vous pouvez supprimer la dépendance sur le lookbehind de largeur variable en utilisant l'ancre \ G (peut-être pouvez-vous l'ajouter à votre réponse): (?: ^ | (?
@ user3163495 Je n'ai pas pensé à \ G . L'inclure dans ma réponse donnerait l'impression de copier la réponse d'anubhava, si vous utilisez une solution basée sur \ G , vous devriez accepter sa réponse plutôt que la mienne
PHP ne prend pas en charge la longueur dynamique en arrière, vous pouvez donc utiliser cette expression régulière en utilisant \G:
\Gabc(?=(?:abc)*$)
\ G affirme sa position à la fin du match précédent ou au début de la chaîne de la première correspondance.
Après quelques itérations supplémentaires, cette expression régulière s'avère la plus efficace:
(?:^(?=(?:abc)+$)|(?!^)\G)abc
J'ai mis l'ancre \ G dans la réponse d'Aaron et cela fonctionne très bien
Après quelques itérations supplémentaires, je pense que \ Gabc (? = (?: abc) * $) sera l'expression rationnelle la plus efficace
Vous pouvez utiliser \ G en combinaison avec une anticipation positive. \ G correspond au début de la chaîne ou affirme la position à la fin de la correspondance précédente.
Vous pouvez capturer abc et vérifier si ce qui se trouve à droite est une répétition du groupe jusqu'à la fin de la chaîne.
\G(abc)(?=\1*$)
Quel est le modèle que vous utilisez? At-il des ancres pour le début et la fin de la chaîne
^et$?@dvo J'ai modifié ma question pour expliquer pourquoi cela ne fonctionne pas
@anubhava J'ai édité ma question pour expliquer pourquoi cela ne fonctionne pas non plus
De quel environnement (langage? Outil?) Utilisez-vous regex?
@Aaron PHP et C #
@anubhava Haha c'est ce que je fais actuellement, et j'essaie de le nettoyer en n'utilisant pas 2 modèles différents