7
votes

Calculer le nombre de caractères consécutifs dans une chaîne en utilisant perl

J'ai une chaîne avec plusieurs séquences de caractères consécutifs tels que: xxx

Je veux représenter ceci comme: a3b2c3d4

à partir de Maintenant, je suis arrivé avec ceci: xxx

sortie: xxx

IT stocke les caractères consécutifs dans le tampon de capture et ne renvoie qu'un seul. Cependant, je souhaite un moyen de compter le nombre de caractères consécutifs dans le tampon de capture, puis d'afficher un seul caractère suivi de ce nombre de ce comptage afin qu'il affiche la sortie comme a3b2c3d4 au lieu de abcd .

Quelle modification est requise à la regex ci-dessus?


0 commentaires

3 Réponses :


11
votes

Cela semble nécessiter l'option "Exécuter" sur la commande de substitution afin que le texte de remplacement soit traité comme un fragment de code Perl: xxx pré>

script h3> xxx

sortie h3> xxx pré>

Pourriez-vous s'il vous plaît casser l'expression régulière pour expliquer comment cela fonctionne? P> blockquote>

Je suppose que c'est la partie correspondante qui est problématique et non la partie de remplacement. em> p>

Le regex d'origine est: p>

((.)\2+)


0 commentaires

1
votes

Les travaux suivants s'ils peuvent vivre avec le ralentissement causé par $ & code>: xxx pré>

Modification du * code> sur code> sur + code> dans l'expression ci-dessus laisse des caractères non consécutifs intacts. p>

comme Jrferguson rappelle, Perl 5.10+ fournit un équivalent $ {^ match} code> variable qui fait Pas affecter les performances de la regex: p> xxx pré>

pour Perl 5.6+, la performance HIT peut toujours être évitée: p>

$str =~ s/(.)\g{1}+/ $1. ( $+[0] - $-[0] ) /ge;


8 commentaires

Merci pour la réponse rapide. Je vais en savoir plus sur les expressions régulières :)


Perl 5.10 introduit $ {^ match} Pour éviter le coup de performance de $ & . Voir Perlre


Pour limiter le succès de la performance, ajoutez le modificateur '\ P' au match. Ensuite, $ {^ premet " $ {^ match} et $ {^ postmatch} ne sont capturés que pour le match en question et pas tout le monde.


@Jrferguson: Je ne vois pas cela faire de la différence au résultat final dans ce cas.


@ZAID: Je ne pensais qu'un peu de clarification de la manière d'éviter que la pénalité de performance pourrait être en ordre. Personnellement, j'ai aimé votre réponse, sans distinction.


Il semble y avoir une émission d'entraînement en série - par rapport à l'électeur non commentaire; Quelqu'un n'aime pas la solution que vous et moi avons donné, mais n'est pas disposé à prendre le temps de fournir sa propre solution ou de commenter pourquoi les votes de descente sont justifiés. C'est une nuisance; ça arrive; Il n'y a pas que l'un ou l'autre de nous peut faire à ce sujet sauf concistrer les uns avec les autres.


@Jrferguson: selon Perldoc Perlre , le / p garantit que $ {^ premet} , $ {^ correspond} et $ {^ postmatch} sera défini dans le événement d'un match réussi. C'est une bonne raison de l'utiliser; Est-ce ce que vous vouliez dire par votre commentaire précédent?


@ZAID: Ma compréhension est que, en utilisant \ p , vous limitez la pénalité au fonctionnement du match au lieu de la prendre partout. C'est-à-dire que si vous utilisez -p le $ {^ premet} , $ {^ correspond} et $ {^ postmatch} $ ne sont définis que pour cette correspondance; Tout le monde --- une amélioration de la performance.



1
votes

JS:

let data = "ababaaaabbbababb";

data.replace(/((.)\2+)/g, (match, p1, p2) =>  {
  data = data.replace(new RegExp(p1, 'g'), p2 + p1.length);
});

console.log(data);


0 commentaires