1

我正在尝试编写一个替换字符串中某些字符的 javascript 函数。例如,如果我想在字符串“ab”中将“a”替换为“ab”,将“b”替换为“c”,函数应该给我字符串“ab c”。在这种情况下,我不能先在字符串上用 'a' 替换,然后在结果上再用 'b' 替换,因为这会给我“ac b”而不是“ab c”。

关于如何有效地做到这一点的任何想法?

4

3 回答 3

5

您可以使用正则表达式来匹配不同的字符,并使用回调函数来确定替换它的内容。因为它在一次运行中完成所有替换,所以一个替换包含另一个要替换的东西没有问题:

s = s.replace(/[ab]/g, function(m){
  switch (m) {
    case 'a': return 'ab';
    case 'b': return 'c';
  }
  return m;
});

演示:http: //jsfiddle.net/Guffa/pXSM5/

编辑:

要使用正则表达式匹配每个字符串,请遍历它们并查找每个匹配项,然后遍历找到的匹配项并替换它们。从字符串中的最后一个开始进行替换是最简单的,这样当替换的长度与匹配的字符串不同时,您不必调整其他匹配项的索引:

var s = "a b";
var re = [{ regex: /a/g, replace: 'ab'}, { regex: /b/g, replace: 'c' }];
var pos = [];

for (var i = 0; i < re.length; i++) {
    while ((r = re[i].regex.exec(s)) != null) {
        pos.push({ index: r.index, match: r[0], replace: re[i].replace });
    }
}

while (pos.length > 0) {
    var last = 0;
    for (var i = 0; i < pos.length; i++) {
        if (pos[i].index > pos[last].index) last = i;
    }
    var p = pos[last];
    s = s.substr(0, p.index) + p.replace + s.substr(p.index + p.match.length);
    pos.splice(last, 1);
}

演示:http: //jsfiddle.net/Guffa/pXSM5/1/

注意:确保正则表达式不匹配任何可以重叠的内容。

于 2013-06-05T07:03:34.943 回答
0

正确的解决方案:正则表达式。“缺点”是它很难学习,(但一旦你学会了,它就完全值得了)。

一个“快速”的解决方案是:

  1. 将 a 替换为极其不寻常(“唯一”)且不得包含“b”的内容
  2. 用你想要的任何东西替换 b
  3. 用ab替换非常不寻常的

像这样

a -> <my_unique_replacement_which_does_not_contain_the_letter_____you_know!>
b -> c
<my_unique_replacement_which_does_not_contain_the_letter_____you_know!> -> ab

它不能保证,它不是一个 100% 的解决方案,可以在任何地方使用,但它是有限使用的快速修复

于 2013-06-05T07:08:40.673 回答
0

我使用数组拆分和替换制作了小代码

var s = "a b ba c",
    re = [['a','ab'], ['b','c'], ['c','d']] ;

var replaced = s.split('').map( function( v ){

    var found = false,
        once = function( c ){
            return function( v ){             
                return found? v: ( found = true && c ) ;
            }
        };

    return re.reduce( function ( a, p ){
        return a.replace( p[0], once( p[1]) ); 
    }, v );

}).join('');

console.log( replaced );

并且replaced有输出ab c cab d

于 2013-06-05T07:22:31.863 回答