3
votes

Comment remplacer des caractères consécutifs et identiques en Perl?

J'ai une chaîne comme XXXXYYYYZZZYYZZZYYYY qui doit être converti en XXXXAAAYZZZAYZZZAAAY

$ s = ~ s / Y {2} + / AY / g;

ceci a 2 problèmes, {2} + obtiendra YYYY à AYAY; et AY n'est pas la même longueur que YYYY (en attendant AAAY )

Comment faire cela en perl?


0 commentaires

3 Réponses :


6
votes

Utilisez un "look-ahead":

$s =~ s/Y(?=Y+)/A/g;

(? = Y +) signifie "suivi d'un ou plusieurs caractères Y ", donc tout caractère Y suivi d'un autre caractère Y sera remplacé par un A.

Plus d'informations sur perlretut


0 commentaires

4
votes

Il y a toujours plus d'une façon de le faire. Ma suggestion est de saisir tous les Y sauf le dernier, puis de l'utiliser pour créer une chaîne de As de même longueur. Le modificateur e dit à perl d'exécuter le code du côté remplacement au lieu de l'utiliser directement, et le modificateur r dit à = ~ de renvoyer le résultat de la substitution au lieu de modifier directement le texte d'entrée (utile pour ces tests à une ligne, entre autres).

$ perl -E 'say shift =~ s/(Y+)(?=Y)/"A"x length$1/gre' XXXXYYYYZZZYYZZZYYYY
XXXXAAAYZZZAYZZZAAAY


3 commentaires

Ce n'est pas vraiment la même chose - vous avez déplacé le + en dehors de la capture, donc la longueur est toujours de 1, et votre remplacement omettra le (s) de fin, et cela signifie que plus de texte est mis en correspondance et donc remplacé. Oui, cela peut fonctionner sans anticipation, mais je préférerais que cela fonctionne.


mon mauvais, ouais (Y +) Y que vous pouvez remplacer par la longueur du groupe capturé comme A et un Y supplémentaire


Regexes: ne fonctionnent généralement pas à la première tentative. :) C'est pourquoi j'ai dû essayer trois fois pour que la réponse ci-dessus fonctionne :)



0
votes

$ s = ~ s / Y {2} + / AY / g
Le modèle RHS est un modèle obscur de manière ambiguë: Y {2} + , c'est un modèle d'expression régulière très rarement utilisé, sauf si {} + est très rarement disponible dans quelques moteurs de regex avancés, y compris perl peut-être, comme une fonctionnalité regex appelée «groupement atomique».
Vous avez peut-être voulu dire (Y {2}) + qui est (YY) + ou Y {2,} qui est YY +
en perl, ce n'est pas une évidence simple et facile car il prend en charge la fonctionnalité lookaround

echo XXXXYYYYZZZYYZZZYYYY |sed -E 's/YY+/&\n/g;s/Y/A/g;s/A\n/Y/g'

en fait un moteur de regex plus bas, un tel sed peut toujours le faire bien que de manière lourde et difficile p >

perl -e '$s=XXXXYYYYZZZYYZZZYYYY ;$s =~ s/Y(?=Y)/A/g;print $s'


0 commentaires