一次替换多个字符串

IT技术 javascript jquery replace
2021-02-09 04:04:19

在 JavaScript 中有一个简单的等价物吗?

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

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

这是使用 PHP 的str_replace,它允许您使用一组单词来查找和替换。我可以使用 JavaScript / jQuery 做这样的事情吗?

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

// string replace here

$("#output").html(textarea);
...
6个回答

您可以使用自己的函数扩展 String 对象,该函数可以满足您的需要(如果缺少功能,则很有用):

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;
};

对于全局替换,您可以使用正则表达式:

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;
};

要使用该函数,它会类似于您的 PHP 示例:

var textarea = $(this).val();
var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];
textarea = textarea.replaceArray(find, replace);
@Tim 这是常规 JavaScript,不需要额外的库。JavaScript 是一种原型语言,这意味着每个对象都有一个它继承的原型。添加到对象的原型只是扩展所有此类对象的一种方式。
2021-03-12 04:04:19
"tar pit".replaceArray(['tar', 'pit'], ['capitol', 'house']) // "cahouseol house"
2021-03-21 04:04:19
此解决方案不适用于以下情况: String: "The cat hits the dog" find array: ['cat', 'dog'] replace array: ['dog, 'cat']
2021-03-21 04:04:19
@derekdreery 该函数不适用于包含RegExp字符的字符串,例如:find array ["(", ")"] 替换 array ["[", "]"]
2021-04-03 04:04:19
谢谢鲍勃,假设这是使用原型(?),你知道如何使用 jQuery 做到这一点吗?
2021-04-04 04:04:19

常见的错误

此页面上的几乎所有答案都使用累积替换,因此存在替换字符串本身需要替换的相同缺陷。以下是此模式失败的几个示例(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'] ) );

解决方案

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'] ) );

笔记:

这是@ elchininet的更加兼容的变化的解决方案,它使用map()Array.indexOf(),因而不会在IE8工作和老年人。

@elchininet 的实现更适用于 PHP 的str_replace(),因为它也允许字符串作为查找/替换参数,并且如果有重复项将使用第一个查找数组匹配(我的版本将使用最后一个)。我在这个实现中没有接受字符串,因为这种情况已经由 JS 的内置String.replace().

@StephenM.Harris 很酷的答案,您也注意到页面中几乎所有的答案都使用累积替换。
2021-03-16 04:04:19
这在替换括号等字符时不起作用。例如,通常使用 ((placeholder)) 样式标签,这将替换那些 ((undefined)) jsfiddle.net/oLfmeaa6/1
2021-03-19 04:04:19
@HoldOffHunger 双数组输入对 PHP 来说更真实,str_replace()这是为了模拟——但除此之外,我也更喜欢对象输入!请记住Object.values,没有 polyfill 将无法在 IE 中工作。
2021-03-25 04:04:19
喜欢这个代码。附录:我将其更改为 replaceBulk(str, obj) {var findArray = Object.keys(obj), var replaceArray = Object.values(obj);....} 所以,我可以传入一个简单的哈希对象{"x":"y"...} 替换。看起来更容易维护。
2021-03-29 04:04:19
@MacroMan 已修复!必须更新转义特殊正则表达式字符的正则表达式(这听起来容易出错:D)。感谢您指出了这一点!
2021-04-03 04:04:19
text = text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>');
@Beejor 公平地说,接受的答案也不是“立即”,它只是将后续替换隐藏在函数后面。
2021-03-22 04:04:19
这不是“一次”。与这个“单行”基本相同: text = text.replace(foo); text = text.replace(bar);
2021-03-23 04:04:19

您可以将String对象的 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]});

提琴手

第二种方法(使用两个数组,查找和替换)

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)]});

提琴手

所需功能:

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);

编辑

function承认 aString或 anArray作为参数:

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)]});
}
嗨@Soyoes,我已经测试过它并且它有效:[jsfiddle](jsfiddle.net/uxv2u9n0
2021-03-13 04:04:19
嗨,我使用第一种方法尝试了类似 {'My':'Your', '[0-1]':'NUM'} 和 str "My name is Peter, Am 19" 的方法。
2021-03-13 04:04:19
看起来很酷,但在某些情况下不起作用:(。例如 {'[0-1]':'NUM'}
2021-03-14 04:04:19
这种方法是搜索和替换StringsArrayStrings它不适用于 RegExp,如果您想将 RegExp 用作搜索参数,则需要解析 findArray以将其转换为RegExp. 我会在几分钟内给你一个例子。
2021-03-31 04:04:19
嗨@Soyoes,告诉我它在什么情况下失败,我会尝试修复它。
2021-04-02 04:04:19

更直观的方法:

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];
  });
};

这就是你的称呼:

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;
错误:this.replace 不是函数!
2021-04-10 04:04:19