【问题标题】:Replace multiple strings at once一次替换多个字符串
【发布时间】:2011-07-01 11:11:14
【问题描述】:

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

【问题讨论】:

  • 只是为了澄清,你这样做是为了逃避html吗?
  • 多个替换而不是单个替换?如果你想有效地做这样的事情,你需要一个正则表达式。这不是所选答案的作用。
  • 看到这个post,我想这就是你要找的东西

标签: javascript jquery replace


【解决方案1】:

您可以使用自己的函数来扩展 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);

【讨论】:

  • 谢谢鲍勃,假设这是使用原型(?)你知道如何使用 jQuery 做到这一点吗?
  • @Tim 这是普通的 JavaScript,不需要额外的库。 JavaScript 是一种原型语言,这意味着每个对象都有一个原型继承自它。添加到对象的原型只是一种扩展所有此类对象的方法。
  • "焦油坑".replaceArray(['tar', 'pit'], ['capitol', 'house']) // "cahouseol house"
  • 此解决方案不适用于以下情况: String: "The cat hits the dog" 查找数组:['cat', 'dog'] 替换数组:['dog, 'cat']
  • @derekdreery 该函数对包含RegExp字符的字符串都不起作用,例如:find array ["(", ")"] replace array ["[", "]"]跨度>
【解决方案2】:

常见错误

此页面上的几乎所有答案都使用累积替换,因此存在替换字符串本身会被替换的相同缺陷。以下是此模式失败的几个示例(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 的solution 的更兼容变体,它使用map()Array.indexOf(),因此在IE8 和更早版本中不起作用。

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

【讨论】:

  • @StephenM.Harris 很酷的答案,您也注意到页面中几乎所有答案都使用累积替换。
  • 这在替换括号等字符时不起作用。例如,通常使用 ((placeholder)) 样式标签,这将替换那些 ((undefined)) jsfiddle.net/oLfmeaa6/1
  • @MacroMan 已修复!必须更新逃避特殊正则表达式字符的正则表达式(这听起来容易出错:D)。感谢您指出这一点!
  • 喜欢这段代码。附录:我将其更改为 replaceBulk(str, obj) {var findArray = Object.keys(obj), var replaceArray = Object.values(obj);....} 所以,我可以传入一个简单的哈希对象{"x":"y"...} 替换。似乎更容易维护。
  • @HoldOffHunger 双数组输入对 PHP 的 str_replace() 更真实,这是为了模拟——但除此之外,我也更喜欢对象输入!请记住,Object.values 在没有 polyfill 的情况下无法在 IE 中运行。
【解决方案3】:
text = text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>');

【讨论】:

  • 这不是“一次”。基本上和这个“单线”一样: text = text.replace(foo); text = text.replace(bar);
  • @Beejor 公平地说,接受的答案也不是“立即”,它只是将后续替换隐藏在函数后面。
【解决方案4】:

您可以将String 对象的替换方法与第二个参数中的函数一起使用:

第一种方法(使用查找和替换对象)

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

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

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

所需功能:

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 承认StringArray 作为参数:

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

【讨论】:

  • 看起来很酷,但在某些情况下不起作用:(。例如 {'[0-1]':'NUM'}
  • 嗨@Soyoes,告诉我在什么情况下它会失败,我会尝试修复它。
  • 嗨@Soyoes,我已经测试过了,它可以工作:[jsfiddle] (jsfiddle.net/uxv2u9n0)
  • 嗨,我用 str "My name is Peter, Am 19" 尝试了类似 {'My':'Your', '[0-1]':'NUM'} 的方法,使用第一种方法。
  • 此方法是搜索替换StringsStringsArray。它不适用于 RegExps,如果您想使用 RegExp 作为搜索参数,您需要解析 find Array 以将其转换为 RegExp。几分钟后我会给你一个例子。
【解决方案5】:

更直观的方法:

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 不是函数!
【解决方案6】:

上面的答案相当于做:

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

鉴于此:

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

在这种情况下,没有进行任何命令式编程。

【讨论】:

    【解决方案7】:

    一个简单的forEach 循环很好地解决了这个问题:

    let text = 'the red apple and the green ball';
    const toStrip = ['red', 'green'];
    toStrip.forEach(x => {
       text = text.replace(x, '');
    });
    
    console.log(text);
    // logs -> the apple and the ball
    

    【讨论】:

      【解决方案8】:

      您可能想研究一个名为 phpJS 的 JS 库。

      它允许您使用 str_replace 函数,就像在 PHP 中使用它一样。还有更多的 php 函数“移植”到 JavaScript。

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

      【讨论】:

        【解决方案9】:
        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
        

        【讨论】:

        • 如果您输入这些变量,此原型将不起作用:var find = [".",","];var replace = [',', '.'];
        【解决方案10】:

        使用 ES6: search 用于字符串,replaceJavaScript 中有很多方法。其中之一如下

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

        【讨论】:

        • 我使用了这种方法,它优雅且有效。不幸的是,YUI 压缩器 2.4.8 无法处理 ES6 并崩溃。
        【解决方案11】:

        没有办法在一个方法调用中做到这一点,您必须将调用链接在一起,或者编写一个手动执行所需操作的函数。

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

        【讨论】:

        • 我喜欢简单。正在从 php 中寻找类似的功能。好的,复制过去 - 但是 3 行 - 没有完整的原型函数。
        【解决方案12】:

        对于标签,你应该可以只用.text()而不是.html()来设置内容。

        示例: http://jsfiddle.net/Phf4u/1/

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

        ...或者如果您只是想删除 &lt;br&gt; 元素,您可以删除 .replace(),并暂时将它们设为 DOM 元素。

        示例: http://jsfiddle.net/Phf4u/2/

        var textarea = $('textarea').val();
        
        textarea = $('<div>').html(textarea).find('br').remove().end().html();
        
        $("#output").text(textarea);
        

        【讨论】:

          【解决方案13】:

          const items = {
            '<': '&lt;',
            '>': '&gt;',
            '\n': '<br/>',
          }
          
          const re = new RegExp('(' + Object.keys(items).join('|') + ')', 'g')
          
          const input = '<foo>\n<bar>'
          
          const output = input.replace(re, ([key]) => items[key])
          
          console.log(output)

          【讨论】:

            【解决方案14】:

            以对象为参数的版本:

            String.prototype.strtr = function (replace) {
                keys = Object.keys(replace);
                result = this;
                for (i = 0; i < keys.length; i++) {
                    result = result.replace(keys[i], replace[keys[i]]);
                }
                return result;
            }
            
            function htmlspecialchars(str) {
                return String(str).strtr({">": "&gt;", "<": "&lt;", "\n": "<br/>"});
            }
            
            // usage
            text = "<span>spam</span>";
            htmlspecialchars(text);
            

            【讨论】:

              【解决方案15】:

              一种方法是:

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

              【讨论】:

                猜你喜欢
                • 2011-12-01
                • 2013-12-05
                • 1970-01-01
                • 2017-10-23
                • 2016-12-03
                • 2020-01-16
                • 2020-11-08
                相关资源
                最近更新 更多