Remplacer plusieurs caractères en un seul appel de remplacement

258

Petite question très simple, mais je ne comprends pas très bien comment faire.

J'ai besoin de remplacer chaque instance de '_' par un espace, et chaque instance de '#' par rien / vide.

var string = '#Please send_an_information_pack_to_the_following_address:';

J'ai essayé ça:

string.replace('#','').replace('_', ' ');

Je n'aime pas vraiment enchaîner des commandes comme celle-ci. Y a-t-il une autre façon de le faire en un seul?

Shannon Hochkins
la source
Voir la réponse à cette question: stackoverflow.com/questions/7072330/…
DeweyOx

Réponses:

517

Utilisez l'opérateur OR ( |):

var str = '#this #is__ __#a test###__';
str.replace(/#|_/g,''); // result: "this is a test"

Vous pouvez également utiliser une classe de caractères:

str.replace(/[#_]/g,'');

Violon

Si vous souhaitez remplacer le hachage par une chose et le trait de soulignement par une autre, il vous suffira de chaîner. Cependant, vous pouvez ajouter un prototype:

String.prototype.allReplace = function(obj) {
    var retStr = this;
    for (var x in obj) {
        retStr = retStr.replace(new RegExp(x, 'g'), obj[x]);
    }
    return retStr;
};

console.log('aabbaabbcc'.allReplace({'a': 'h', 'b': 'o'}));
// console.log 'hhoohhoocc';

Mais pourquoi ne pas enchaîner? Je ne vois rien de mal à cela.

tckmn
la source
C'est cool, mais je dois remplacer les traits de soulignement par des espaces non vides, puis-je le faire?
Shannon Hochkins
C'est ce que je pensais, mais vous m'avez quand même aidé à comprendre comment les expressions de remplacement fonctionnent un peu mieux :)
Shannon Hochkins
Votre prototype ne fonctionne pas? pouvez-vous fournir un exemple sur le violon, je continue à recevoir des erreurs
Shannon Hochkins
3
Une autre option pour #|_est [#_], et vous pourriez aussi bien utiliser +pour faire correspondre tous les matchs consécutifs pour améliorer les performances
Ian
3
Cool merci ... si besoin, remplacez les espaces vides et d'autres symboles str.replace(/[+ -]/g,'');mettez simplement un espace vide au milieu.
equiman
53

Le chaînage est cool, pourquoi le rejeter?

Quoi qu'il en soit, voici une autre option en un seul remplacement:

string.replace(/#|_/g,function(match) {return (match=="#")?"":" ";})

Le remplaçant choisira "" si match == "#", "" sinon.

[Mise à jour] Pour une solution plus générique, vous pouvez stocker vos chaînes de remplacement dans un objet:

var replaceChars={ "#":"" , "_":" " };
string.replace(/#|_/g,function(match) {return replaceChars[match];})
Christophe
la source
4
var regex = new RegExp( Object.keys(replaceChars).join("|"), "g"); string.replace(regex,function(match) {return replaceChars[match];})faites le pas supplémentaire: cela facilite la modification des replaceChars.
RozzA
@RozzA merci. Object.keys n'était pas courant à l'époque.
Christophe
J'ai totalement oublié l'option de fonction de remplacement pour remplacer le deuxième paramètre, pour m'aider à me souvenir :)
Luckylooke
48

Si vous souhaitez remplacer plusieurs caractères, vous pouvez appeler le String.prototype.replace()avec l'argument de remplacement étant une fonction qui est appelée pour chaque correspondance. Tout ce dont vous avez besoin est un objet représentant le mappage de caractères que vous utiliserez dans cette fonction.

Par exemple, si vous souhaitez aremplacer par x, bavec yet cavec z, vous pouvez faire quelque chose comme ceci:

var chars = {'a':'x','b':'y','c':'z'};
var s = '234abc567bbbbac';
s = s.replace(/[abc]/g, m => chars[m]);
console.log(s);

Sortie :234xyz567yyyyxz

Voicu
la source
3
puisque vous utilisez ES6 (fonction flèche), vous devez également remplacer varpar constici. une alternative pour une prise en charge étendue du navigateur:var s ='234abc567bbbbac'; s = s.replace(/[abc]/g, function(m) { return {'a':'x','b':'y','c':'z'}[m]; }); console.log(s);
Felix Geenen
1
@FelixGeenen 1. vous tuez la portabilité 2. si vous choisissez de redéfinir les caractères ou les s, vous obtiendrez une erreur d'exécution, qui tue sa robustesse, 3. il n'y a aucune garantie pour protéger les s contre les mutations et les reliures autres que purement idéologiques. C'est une chose merveilleuse de voir que cet extrait fonctionnera toujours dans windows98 fraîchement installé sur double-clic / cscript / wscript:var chars = {a:'1', b:'2', c:'3'}; var s = '123abc123'; var u = s.replace(/[abc]/g, function(m) { return chars[m]; }); WScript.echo(u);
Dmitry
Ceci est vraiment bon. Merci. Quelle est la partie où vous avez utilisé un objet pour faire une instruction ou. avez-vous une documentation ou une référence à quelque chose qui explique cela. Très bon cas d'utilisation.
Christian Matthew
39

Spécifiez l' /gindicateur (global) sur l'expression régulière pour remplacer toutes les correspondances au lieu de la première:

string.replace(/_/g, ' ').replace(/#/g, '')

Pour remplacer un caractère par une chose et un caractère différent par quelque chose d'autre, vous ne pouvez pas vraiment vous déplacer en ayant besoin de deux appels distincts vers replace. Vous pouvez l'abstraire dans une fonction comme Doorknob l'a fait, bien que je l'aurais probablement pris un objet avec d'anciens / nouveaux comme paires clé / valeur au lieu d'un tableau plat.

Mark Reed
la source
comment pourrais-je inclure le hachage aussi?
Shannon Hochkins
4

Vous pouvez également essayer ceci:

function replaceStr(str, find, replace) {
    for (var i = 0; i < find.length; i++) {
        str = str.replace(new RegExp(find[i], 'gi'), replace[i]);
    }
    return str;
}

var text = "#here_is_the_one#";
var find = ["#","_"];
var replace = ['',' '];
text = replaceStr(text, find, replace);
console.log(text);

findfait référence au texte à rechercher et replaceau texte à remplacer par

Cela remplacera les caractères insensibles à la casse. Pour faire autrement, changez simplement les drapeaux Regex comme requis. Par exemple: pour la casse, remplacez:

new RegExp(find[i], 'g')
Tapan Bala
la source
4

Vous pouvez simplement essayer ceci:

str.replace(/[.#]/g, 'replacechar');

cela remplacera., - et # par votre remplacechar!

karim somai
la source
Cette réponse a déjà été fournie et ne gère pas le remplacement de différents caractères par d'autres caractères, voir OP.
Shannon Hochkins
3

Voici un moyen simple de le faire sans RegEx.
Vous pouvez prototyper et / ou mettre en cache des choses comme vous le souhaitez.

// Example: translate( 'faded', 'abcdef', '123456' ) returns '61454'
function translate( s, sFrom, sTo ){
    for ( var out = '', i = 0; i < s.length; i++ ){
        out += sTo.charAt( sFrom.indexOf( s.charAt(i) ));
    }
    return out;
}
Beejor
la source
Je sais que vous ne l'avez pas dit, mais n'est-il pas beaucoup plus élégant d'utiliser simplement l'expression régulière? str.replace(/#|_/g,'')
Shannon Hochkins
1
@ShannonHochkins Bien sûr! Je ne veux pas dénigrer RegEx; Je montre juste une autre option. RegEx n'est pas toujours intuitif et se prête à être utilisé "comme un marteau, traitant chaque problème comme un clou". De plus, en regardant les autres réponses, en tant que fonction réutilisable, celle-ci n'est pas beaucoup plus longue et les paramètres sont faciles à comprendre. Personnellement, j'irais avec un court RegEx pour la question ici, et il est logique si vous cherchez juste un extrait rapide que vous ne craignez pas de ne pas comprendre complètement.
Beejor
Eh bien, si vous avez besoin de traduire un caractère (à la commande sed y ou à la Unix tr), cela semble être la bonne réponse.
Édouard
3

S'il vous plaît essayez:

  • remplacer la chaîne multiple

    var str = "http://www.abc.xyz.com"; str = str.replace(/http:|www|.com/g, ''); //str is "//.abc.xyz"

  • remplacer plusieurs caractères

    var str = "a.b.c.d,e,f,g,h"; str = str.replace(/[.,]/g, ''); //str is "abcdefgh";

Bonne chance!

Tran Hung
la source
2

Vous pouvez également passer un objet RegExp à la méthode replace comme

var regexUnderscore = new RegExp("_", "g"); //indicates global match
var regexHash = new RegExp("#", "g");

string.replace(regexHash, "").replace(regexUnderscore, " ");

Javascript RegExp

Michael Sanchez
la source
OP ne veut pas enchaîner les replaceappels - cela ne permet pas d'éviter cela.
Dennis
2

yourstring = '#Please send_an_information_pack_to_the_following_address:';

remplacer '#' par '' et remplacer '_' par un espace

var newstring1 = yourstring.split('#').join('');
var newstring2 = newstring1.split('_').join(' ');

newstring2 est votre résultat

Hafsul Maru
la source
Votre réponse n'utilise pas un fragment de jQuery, et ne suit pas non plus l'OP, '#this #is__ #a test ### ' .split ('_'). Join ('') ne fonctionnerait pas comme vous vous retrouveriez avec plus d'espace
Shannon Hochkins
@ShannonHochkins Comment plus d'espaces blancs seront-ils ajoutés?
Hafsul Maru
Jetez un oeil à mon exemple, quand il y a un trait de soulignement avant un espace, ou deux traits de soulignement vous vous retrouverez avec plusieurs espaces.
Shannon Hochkins
@ShannonHochkins le questionneur traite de la chaîne '#Please send_an_information_pack_to_the_following_address:'; il n'y a pas d'espace ici. pourquoi j'y penserai. quand pensez, pourquoi seulement à propos de l'espace, beaucoup d'autres choses peuvent arriver.
Hafsul Maru
Je vous suggère de relire l'OP, je suis l'affiche originale et vous pouvez voir clairement dans ma première variable var str = '#this #is__ __#a test###__';qu'il y a clairement plusieurs espaces dans cette chaîne.
Shannon Hochkins
2

Voici une autre version utilisant String Prototype. Prendre plaisir!

String.prototype.replaceAll = function(obj) {
    let finalString = '';
    let word = this;
    for (let each of word){
        for (const o in obj){
            const value = obj[o];
            if (each == o){
                each = value;
            }
        }
        finalString += each;
    }

    return finalString;
};

'abc'.replaceAll({'a':'x', 'b':'y'}); //"xyc"
Diego Fortes
la source
1

Je ne sais pas si cela va aider mais je voulais retirer <b>et </b>de ma chaîne

donc j'ai utilisé

mystring.replace('<b>',' ').replace('</b>','');

Donc, fondamentalement, si vous voulez réduire un nombre limité de caractères et ne perdez pas de temps, cela sera utile.

Hrishikesh Kale
la source
-1

Voici une fonction «HTML sécurisée» utilisant une fonction de remplacement multiple «réduire» (cette fonction applique chaque remplacement à la chaîne entière, donc les dépendances entre les remplacements sont importantes).

// Test:
document.write(SafeHTML('<div>\n\
    x</div>'));

function SafeHTML(str)
    {
    const replacements = [
        {'&':'&amp;'},
        {'<':'&lt;'},
        {'>':'&gt;'},
        {'"':'&quot;'},
        {"'":'&apos;'},
        {'`':'&grave;'},
        {'\n':'<br>'},
        {' ':'&nbsp;'}
        ];
    return replaceManyStr(replacements,str);
    } // HTMLToSafeHTML

function replaceManyStr(replacements,str)
    {
    return replacements.reduce((accum,t) => accum.replace(new RegExp(Object.keys(t)[0],'g'),t[Object.keys(t)[0]]),str);
    }
David Spector
la source
Merci pour le message, mais il est assez complet par rapport à la réponse acceptée
Shannon Hochkins
La réponse à la question est une fonction d'une ligne. Comment est-ce "extensif"? La sécurisation des entrées des utilisateurs est un exemple important. Tu es trop critique. «réduire» est une technique très utile que vous devez connaître.
David Spector
J'ai dit que votre réponse est trop complète, c'est beaucoup plus de code, vous utilisez des expressions régulières de toute façon, rendant le processus trop compliqué, vous ne savez pas comment vous pensez que votre réponse est une réduction par rapport à l'une de ces réponses ...
Shannon Hochkins
Ma réponse est une réponse «réduire» car elle utilise la fonction Array.prototype.reduce. Une réponse plus courte pourrait utiliser une chaîne au lieu des clés de propriété, exploitant le fait qu'une fonction "HTML sûr" ne fonctionne que pour remplacer des caractères uniques. Je vous mets au défi de trouver une réponse plus élégante au lieu de vous plaindre grossièrement en public comme ça.
David Spector
En fait, j'ai dit merci, et je vous ai critiqué, vous avez pris cela et décidé d'écrire quelque chose de sarcastique, si nous allons commencer par des méthodes fonctionnelles à exécuter plutôt que des méthodes chaînées prototypiques comme nous devrions l'être, alors quelque chose de beaucoup plus simple comme: jsfiddle .net / shannonhochkins / xsm9j610 / 21
Shannon Hochkins