替换单词数组

4
x.replace(/old/gi. 'new');
x.replace(/whatever/gi. 'whatevernew');
x.replace(/car/gi. 'boat');

有没有办法将这些内容组合成一个正则表达式语句,然后再加上旧词和新词的数组。PHP解决方案也可以。

2
我认为你会对这个链接有很好的使用。 - Ibu
6个回答

2
你可以尝试像这样做:
var x = 'The old car is just whatever';
var arr = [{ old: /old/gi, new: 'new' },
           { old: /whatever/gi, new: 'whatevernew' },
           { old: /car/gi, new: 'boat' }];

for (var ii = 0; ii < arr.length; ii++) {
    x = x.replace(arr[ii].old, arr[ii].new);
}

实际上,即使是替换单词,您也需要使用正则表达式。此代码仅替换每个单词一次,并且区分大小写。您需要 x.replace(new RegExp(arr[ii].old, 'gi'), arr[ii].new) - Kobi

2
和RobG提出了一种使用回调函数的有趣方法。这里是一个更加通用的版本,你可以通过传递一个数据结构参数来指定要替换的内容和替换为什么内容。
function multiReplace(str, params) {
    var regStr = "";
    for (var i in params) {
        regStr += "(" + i + ")|";    // build regEx string
    }
    regStr = regStr.slice(0, -1);   // remove extra trailing |
    return(str.replace(new RegExp(regStr, "gi"), function(a) {
        return(params[a]);
    }));
}


var test = 'This old car is just whatever and really old';
var replaceParam = {"old": "new", "whatever": "something", "car": "boat"};

var result = multiReplace(test, replaceParam);
alert(result);

这里有一个演示它工作的示例: http://jsfiddle.net/jfriend00/p8wKH/


1

试试这个:

var regexes = { 'new': /old/gi, 'whatevernew': /whatever/gi, 'boat': /car/gi };

$.each(regexes, function(newone, regex){
  x = x.replace(regex, newone);
});

或者这样:

var regexes = { 'old':'new', 'whatever':'whatevernew', 'car':'boat'};

$.each(regexes, function(oldone, newone){
  x = x.replace(new RegExp(oldone, 'gi'), newone);
});

1
问题在于顺序未定义:whatevernew可能会在whatevernew之前被替换,因此您可能会在不同的迭代(或至少不同的浏览器)中获得不同的结果。 - Kobi
@Kobi 我认为它会按顺序处理。我找不到关于 jQuery.each() 的顺序的任何资源。你有吗? - Sanghyun Lee
例如这个:https://dev59.com/L3VC5IYBdhLWcg3wnCWA,或者这个:https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in#Description。它不是特定于`jQuery.each`:对象属性之间没有顺序。无论`jQuery.each`如何实现,您都不能依赖变量`regexes`的定义。您编写属性的顺序不保证在内部保持不变。 - Kobi

1

replace方法支持使用回调函数:

var x = 'This old car is just whatever';
var y = x.replace(/(old)|(whatever)|(car)/gi,function (a) {
    var str = "";

    switch(a){
      case "old":
         str = "new";
         break;
      case "whatever":
         str = "something";
         break;
      case "car":
         str = "boat";
         break;
      default: 
         str= "";
    }
    return str;
});
alert(y);

// Y will print "This new car is just something"

我认为使用 switch 语句会更好。 - Sanghyun Lee
我最喜欢这个。+1 不过,回调函数可以简化为一个语句(请参阅我的解决方案)。 - ridgerunner

1

这里还有几个:

// Multi RegExp version
var replaceSeveral = (function() {
  var data = {old:'new', whatever: 'whatevernew', car: 'boat'};

  return function(s) {
    var re;
    for (var p in data) {
      if (data.hasOwnProperty(p)) {
        re = new RegExp('(^|\\b)' + p + '(\\b|$)','ig');
        s = s.replace(re, '$1' + data[p] + '$2');
      }
    }
    return s;
  }
}());

// Replace function version
var comparitor = (function() {
  var data = {old:'new', whatever: 'whatevernew', car: 'boat'};
  return function (word) {
    return data.hasOwnProperty(word.toLowerCase())? data[word] : word;
  }
}());


var s = 'old this old whatever is a car';
alert(
  s 
  + '\n' + replaceSeveral(s)
  + '\n' + s.replace(/\w+/ig, comparitor)

);

1

Ibu的回调解决方案非常干净,但可以进一步简化:

x = x.replace(/\b(?:old|whatever|car)\b/gi,
        function (m0) {
            return {'old': 'new',
                    'car': 'boat',
                    'whatever': 'something'}[m0];
        });

使用对象文字的技巧非常有效。我修改了正则表达式以匹配完整单词,通过添加单词边界(避免将gold更改为gnew等)。

编辑:经过仔细检查,我发现jfriend00的解决方案正在使用相同的技术(并且是通用的,更加有用)。


看了所有提供的解决方案,似乎我的原始代码比这里提供的大多数答案更短更高效。为大家的努力点赞。 - Pinkie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接