web-dev-qa-db-fra.com

Remplacer plusieurs chaînes à la fois

Existe-t-il un équivalent facile à cela en JavaScript?

$find = array("<", ">", "\n");
$replace = array("&lt;", "&gt;", "<br/>");

$textarea = str_replace($find, $replace, $textarea); 

Ceci utilise PHP str_replace, qui vous permet d'utiliser un tableau de mots à rechercher et à remplacer. Puis-je faire quelque chose comme ça en utilisant JavaScript/jQuery?

...
var textarea = $(this).val();

// string replace here

$("#output").html(textarea);
...
58
Tim

Vous pouvez étendre l'objet String avec votre propre fonction qui fait ce dont vous avez besoin (utile en cas de fonctionnalité manquante):

String.prototype.replaceArray = function(find, replace) {
  var replaceString = this;
  for (var i = 0; i < find.length; i++) {
    replaceString = replaceString.replace(find[i], replace[i]);
  }
  return replaceString;
};

Pour un remplacement global, vous pouvez utiliser regex:

String.prototype.replaceArray = function(find, replace) {
  var replaceString = this;
  var regex; 
  for (var i = 0; i < find.length; i++) {
    regex = new RegExp(find[i], "g");
    replaceString = replaceString.replace(regex, replace[i]);
  }
  return replaceString;
};

Pour utiliser la fonction, cela ressemblerait à votre exemple PHP:

var textarea = $(this).val();
var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];
textarea = textarea.replaceArray(find, replace);
77
Bob

Erreur commune

Presque toutes les réponses sur cette page utilisent le remplacement cumulatif et souffrent donc du même défaut lorsque les chaînes de remplacement sont elles-mêmes susceptibles d’être remplacées. Voici quelques exemples où ce modèle échoue (h/t @KurokiKaze @derekdreery):

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

// Fails in some cases:
console.log( replaceCumulative( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceCumulative( "you & me", ['you','me'], ['me','you'] ) );

Solution

function replaceBulk( str, findArray, replaceArray ){
  var i, regex = [], map = {}; 
  for( i=0; i<findArray.length; i++ ){ 
    regex.Push( findArray[i].replace(/([-[\]{}()*+?.\\^$|#,])/g,'\\$1') );
    map[findArray[i]] = replaceArray[i]; 
  }
  regex = regex.join('|');
  str = str.replace( new RegExp( regex, 'g' ), function(matched){
    return map[matched];
  });
  return str;
}

// Test:
console.log( replaceBulk( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceBulk( "you & me", ['you','me'], ['me','you'] ) );

Remarque: 

Ceci est une variante plus compatible de la solution solution de @ elchininet, qui utilise map() et Array.indexOf() et ne fonctionnera donc pas dans IE8 et les versions antérieures. 

L'implémentation de @ elchininet est conforme à la fonction str_replace() de PHP, car elle autorise également les chaînes en tant que paramètres de recherche/remplacement, et utilisera la première correspondance de tableau de recherche s'il existe des doublons (ma version utilisera le dernier). Je n'ai pas accepté les chaînes dans cette implémentation car ce cas est déjà traité par la fonction String.replace() intégrée de JS.

26
Stephen M. Harris
text = text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>');
16
hsz

Une approche plus visuelle:

String.prototype.htmlProtect = function() {
  var replace_map;

  replace_map = {
    '\n': '<br />',
    '<': '&lt;',
    '>': '&gt;'
  };

  return this.replace(/[<>\n]/g, function(match) { // be sure to add every char in the pattern
    return replace_map[match];
  });
};

et voici comment vous l'appelez:

var myString = "<b>tell me a story, \n<i>bro'</i>";
var myNewString = myString.htmlProtect();

// &lt;b&gt;tell me a story, <br />&lt;i&gt;bro'&lt;/i&gt;
8
Utopik

Vous pouvez utiliser la méthode replace de l'objet String avec une fonction dans le deuxième paramètre:

Première méthode (utilisant un objet find and replace)

var findreplace = {"<" : "&lt;", ">" : "&gt;", "\n" : "<br/>"};

textarea = textarea.replace(new RegExp("(" + Object.keys(findreplace).map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return findreplace[s]});

jsfiddle

Deuxième méthode (en utilisant deux tableaux, rechercher et remplacer)

var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];

textarea = textarea.replace(new RegExp("(" + find.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return replace[find.indexOf(s)]});

jsfiddle

Fonction souhaitée:

function str_replace($f, $r, $s){
   return $s.replace(new RegExp("(" + $f.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return $r[$f.indexOf(s)]});
}

$textarea = str_replace($find, $replace, $textarea);

MODIFIER

Cette function admet une String ou une Array en tant que paramètres:

function str_replace($f, $r, $s){
    return $s.replace(new RegExp("(" + (typeof($f) == "string" ? $f.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&") : $f.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|")) + ")", "g"), typeof($r) == "string" ? $r : typeof($f) == "string" ? $r[0] : function(i){ return $r[$f.indexOf(i)]});
}
7
ElChiniNet

Vous voudrez peut-être examiner une bibliothèque JS appelée phpJS.

Cela vous permet d'utiliser la fonction str_replace de la même manière que vous l'utiliseriez en PHP. Il y a aussi beaucoup plus de fonctions php "portées" sur JavaScript.

http://phpjs.org/functions/str_replace:527

4
Matt Rardon
String.prototype.replaceArray = function (find, replace) {
    var replaceString = this;
    for (var i = 0; i < find.length; i++) {
        // global replacement
        var pos = replaceString.indexOf(find[i]);
        while (pos > -1) {
            replaceString = replaceString.replace(find[i], replace[i]);
            pos = replaceString.indexOf(find[i]);
        }
    }
    return replaceString;
};

var textT = "Hello world,,,,, hello people.....";
var find = [".",","];
var replace = ['2', '5'];
textT = textT.replaceArray(find, replace);
// result: Hello world55555 hello people22222
3
user1925159

Pour les balises, vous devriez pouvoir définir le contenu avec .text() au lieu de .html().

Exemple:http://jsfiddle.net/Phf4u/1/

var textarea = $('textarea').val().replace(/<br\s?\/?>/, '\n');

$("#output").text(textarea);

... ou si vous vouliez simplement supprimer les éléments <br>, vous pouvez supprimer la .replace() et en faire temporairement des éléments DOM.

Exemple:http://jsfiddle.net/Phf4u/2/

var textarea = $('textarea').val();

textarea = $('<div>').html(textarea).find('br').remove().end().html();

$("#output").text(textarea);
2
user113716

Il n'y a aucun moyen de faire cela dans un appel de méthode, vous devez soit chaîner les appels ensemble, soit écrire une fonction qui fait manuellement ce que vous avez besoin.

var s = "<>\n";
s = s.replace("<", "&lt;");
s = s.replace(">", "&gt;");
s = s.replace("\n", "<br/>");
2
Bryan Kyle

La meilleure réponse est équivalente à faire:

let text = find.reduce((acc, item, i) => {
  const regex = new RegExp(item, "g");
  return acc.replace(regex, replace[i]);
}, textarea);

Compte tenu de ceci:

var textarea = $(this).val();
var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];

Dans ce cas, aucune programmation impérative n'est en cours.

1
Jose Canizares

Utilisation de ES6: Il existe plusieurs façons de search pour les chaînes et replace dans JavaScript. L'un d'eux est comme suit

const findFor = ['<', '>', '\n'];

const replaceWith = ['&lt;', '&gt;', '<br/>'];

const originalString = '<strong>Hello World</strong> \n Let\'s code';

let modifiedString = originalString;

findFor.forEach( (tag, i) => modifiedString = modifiedString.replace(new RegExp(tag, "g"), replaceWith[i]) )

console.log('Original String: ', originalString);
console.log('Modified String: ', modifiedString);

0
Niraj Kaushal

J'ai eu un cas où je devais supprimer des caractères d'une chaîne et l'a fait comme ceci:

 let badChars = ['å', 'ä', 'ö'];
 let newName = fileName.split("").filter((chr) => badChars.indexOf(chr) === -1).join("");

Cela aurait été très soigné si les chaînes étaient intrinsèquement des tableaux de caractères en javascript, de sorte que nous n'aurions pas eu besoin de ces scissions/jointures, comme newName = fileName.filter((chr) => badChars.indexOf(chr) === -1), mais je pense toujours que c'est net et lisible si vous devez uniquement traiter avec des caractères et non avec des chaînes.

0
Alex

Une méthode serait:

var text = $(this).val();
text = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
$("#output").html(text);
0
James Sumners