Comment puis-je faire correspondre des chaînes qui ne correspondent pas à un modèle particulier en Perl?
Je sais que c'est facile pour correspondre à tout, sauf à un personnage donné à l'aide d'une expression régulière.
$text = "ab ac ad";
$text =~ s/[^c]*//g; # Match anything, except c.
$text is now "c".
Je ne sais pas comment "à l'exception" des cordes à la place des personnages. Comment pourrais-je "correspond à quoi que ce soit, à l'exception de 'ac'" ? Essayé [^(ac)] et [^"ca"], sans succès.
Est-il possible?
source d'informationauteur ssn | 2010-01-21
Vous devez vous connecter pour publier un commentaire.
Suivantes résout la question comprise dans le deuxième sens décrit Bart K. commentaire:
Aussi,
'abacadac'
->'acac'
Il convient de noter cependant que dans la plupart des applications pratiques négatives lookaheads s'avérer plus utile que de cette approche.
Si vous voulez juste pour vérifier si la chaîne ne contient pas de "ac", il suffit d'utiliser une négation.
ou
@ssn
Quelques commentaires au sujet de votre question:
"#" est.
le"*". "[^c]" s'entend de la
la classe de caractères composée de tous les
les caractères à l'exception de la lettre "c".
Ensuite, vous utilisez le /g modificateur,
ce qui signifie que toutes ces occurrences dans le texte sera
remplacé (dans votre exemple, avec
rien). Le "zéro" ("*")
modificateur est donc redondant.
Veuillez lire la documentation sur les classes de caractères(Voir "perldoc perlre" sur votre ligne de commande, ou en ligne à http://perldoc.perl.org/perlre.html ) - vous allez le voir, pour que la liste des caractères à l'intérieur des parenthèses la RE sera "correspond à un caractère de la liste". Sens de l'ordre n'est pas pertinent et il n'y a pas de "chaînes", seulement une liste de caractères. "()" et les guillemets aussi n'ont pas de signification particulière dans les crochets.
Maintenant, je ne suis pas sûr de savoir exactement pourquoi vous parlez de correspondance, mais de donner un exemple de substitution. Mais pour voir si une chaîne ne correspond pas à la sous-chaîne "ca" vous avez juste besoin de nier le match:
Dire que vous avez une chaîne de texte dans lequel sont incorporés plusieurs occurrences d'une sous-chaîne. Si vous voulez juste le texte qui entoure la sous-chaîne de caractères, il suffit de retirer toutes les occurrences de la sous-chaîne:
Si vous voulez l'inverse - pour supprimer tout le texte, sauf pour toutes les occurrences de la sous-chaîne, je dirais quelque chose comme:
En fait cela compte le nombre de fois que la sous-chaîne apparaît dans le texte et imprime la sous-chaîne de caractères que le nombre de fois à l'aide de la "x" de l'opérateur. Pas très élégant, je suis sûr que Perl-guru pourrait trouver quelque chose de mieux.
@ennuikiller:
C'est incorrect, car il génère un avertissement ("Inutile d'utiliser de l'évolution négative de liaison (!~) dans le contexte vide") sous "utiliser les mises en garde" et ne fait rien, sauf supprimer toutes les sous-chaînes "ac" du texte, qui pourrait être plus simplement écrit comme je l'ai écrit ci-dessus avec:
Mise à jour: Dans un commentaire sur votre question, vous avez mentionné que vous voulez nettoyer le balisage wiki et supprimer équilibrée des séquences de
{{
...}}
. L'article 6 de la FAQ Perl couvre ce: Puis-je utiliser les expressions régulières de Perl pour correspondre texte équilibré?Considérons le programme suivant:
Sa sortie:
Pour votre exemple, vous pouvez utiliser
Qui est, seulement supprimer une
a
ouc
quand ils ne font pas partie d'unac
séquence.En général, c'est difficile à faire avec une expression régulière.
Dire que vous ne voulez pas
foo
suivie par des espaces facultatifs et puisbar
dans$str
. Souvent, c'est plus clair et plus facile à contrôler séparément. Par exemple:Vous pourriez également être intéressé par une réponse à une question similaireoù j'ai écrit
Pour comprendre la complication, lire Comment Regexes Travail par Mark Dominus. La compile des expressions régulières dans des machines d'état. Quand il est temps de match, il se nourrit de la chaîne d'entrée à l'état de la machine et vérifie si l'état de la machine termine dans une accepter de l'état. Afin d'exclure une chaîne, vous devez spécifier une machine qui accepte toutes les entrées sauf une séquence particulière.
Ce qui pourrait aider est un
/v
expression régulière interrupteur qui crée l'état de la machine comme d'habitude, mais complète alors l'accepter état-bit pour tous les états. Il est difficile de dire si ce serait vraiment utile par rapport à séparer les contrôles parce qu'un/v
expression régulière peut encore surprendre les gens, juste de différentes manières.Si vous êtes intéressé par l'théorique de détails, voir Une Introduction aux Langages Formels et Automates par Peter Linz.
vous pouvez utiliser l'index()
Vous pouvez facilement modifier cette regex pour votre but.