Comment remplacer toutes les occurrences d'un caractère avec deux personnages en utilisant std::string?
Est là une belle façon simple de remplacer toutes les occurrences de "/"
dans un std::string
avec "\/"
d'échapper à toutes les barres obliques dans un std::string
?
Vous devez vous connecter pour publier un commentaire.
Probablement la façon la plus simple de le faire est avec stimuler la chaîne des algorithmes de la bibliothèque.
La réponse est non... il n'est pas "facile" si vous voulez dire un one-liner déjà fournis par la bibliothèque standard. Cependant, il n'est pas difficile à mettre en œuvre cette fonction.
Tout d'abord, je pense que, probablement, vous aurez également besoin de remplacer
\
avec\\
et autres caractères spéciaux. Dans ce cas, à l'aide de lareplaceAll
de mise en œuvre donnés par ildjarn va être ennuyeux (vous aurez besoin de remplacer la même chaîne à plusieurs reprises).À mon avis il y a beaucoup de cas de la chaîne de transformation, où rien ne vaut l'aide d'un explicite
char *
approche. Dans ce cas précis, cependant, probablement à l'aide d'un index est une bonne chose:L'idée de base est de se déplacer sur la chaîne et l'ajout d'un supplément
\
caractère avant tout caractère spécial (ci-dessus j'ai juste géré/
et\
, mais vous voyez l'idée).Le résultat est connu pour être au maximum de
2*n
de longueur, donc je préallouer en faisant tout le traitement de O(n) (lereplaceAll
approche continue de bouger le reste de la corde à droite, rendant O(n^2)).Même pour de courtes chaînes de caractères comme
"this is a test with /slashes/that should be /escaped/"
la fonction ci-dessus est sur mon PC le plus performant (1,3 x en vitesse), même si l'appel dereplaceAll
juste une fois et la manipulation au lieu de deux caractères spéciaux dansescape
.Note également que cette fonction retourne naturellement une chaîne distincte au lieu de modifier la corde en place (OMI une meilleure interface) et dans le moment de la comparaison, j'ai dû créer une chaîne de caractères pour chaque appel, de sorte que les résultats sont même déplacé vers l'égalité en raison de l'ajout de la constante de temps.
Le au-dessus de lecture/écriture approche peut également être facilement étendu aux plus complexes, des substitutions (par exemple, le remplacement de
>
avec>
ou des caractères non imprimable gamme avec%xx
encodage) en conservant une bonne efficacité pour les grandes chaînes de caractères (un seul passage).Un exemple sur la façon de le faire est donné sur la cppreference.com
std::string::remplacez
de la page:O(n*m)
oùn
est la longueur de la chaîne etm
est le nombre de remplacements sifrom
etto
ont des durées différentes, car pour chaque remplacement, il doit déplacer la queue de la chaîne.std::string::remplacez
Pour remplacer toutes les occurrences d'une sous-chaîne dans une chaîne de caractères par une autre sous-chaîne:
De sortie:
J'ai extrapolé sur la question, pour faire une streaming la mise en œuvre d'permet d'échapper à une variété de personnages.
Streaming prend vraiment le biscuit pour les grands volumes[1], parce que vous obtiendrez dans la fragmentation du segment/la performance de l'enfer autrement. Aussi, cela permet d'échapper les chaînes stockées dans tout type de source, comme les exemples ne montrent
Voir en Direct Sur Coliru
J'ai choisi un interrupteur, car il sera optimisé par le compilateur. Pour des ensembles dynamiques de escapable personnages, je préfère une sorte de recherche (un vecteur avec des std::find ferait, bien que pour les grands ensembles d'un std::set de set::trouver deviendrait le meilleur choix).
Espère que cette aide
[1] voir, par exemple, cette belle bug j'ai récemment rencontré: GParted: Simplifié cleanup_cursor() de la mise en œuvre