多个特殊字符替换优化

时间:2012-09-24 16:16:43

标签: javascript jquery string special-characters

我需要用 javascript 或jQuery替换字符串中的所有特殊字符。
我相信有更好的方法可以做到这一点 但我目前没有任何线索 有人有想法吗?

function Unaccent(str) {
    var norm = new Array('À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë','Ì','Í','Î','Ï', 'Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø','Ù','Ú','Û','Ü','Ý','Þ','ß', 'à','á','â','ã','ä','å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð','ñ', 'ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý','ý','þ','ÿ');
    var spec = new Array('A','A','A','A','A','A','A','C','E','E','E','E','I','I','I','I', 'D','N','O','O','O','0','O','O','U','U','U','U','Y','b','s', 'a','a','a','a','a','a','a','c','e','e','e','e','i','i','i','i','d','n', 'o','o','o','o','o','o','u','u','u','u','y','y','b','y');
    for (var i = 0; i < spec.length; i++) {
        str = replaceAll(str, norm[i], spec[i]);
    }
    return str;
}

function replaceAll(str, search, repl) {
    while (str.indexOf(search) != -1) {
        str = str.replace(search, repl);
    }
    return str;
}

3 个答案:

答案 0 :(得分:4)

这是一个使用查找映射的版本,它比嵌套循环更有效:

function Unaccent(str) {
    var map = Unaccent.map;       // shortcut
    var result = "", srcChar, replaceChar;
    for (var i = 0, len = str.length; i < len; i++) {
        srcChar = str.charAt(i);
        // use hasOwnProperty so we never conflict with any 
        // methods/properties added to the Object prototype
        if (map.hasOwnProperty(srcChar)) {
            replaceChar = map[srcChar]
        } else {
            replaceChar = srcChar;
        }
        result += replaceChar;
    }
    return(result);
}

// assign this here so it is only created once
Unaccent.map = {'À':'A','Á':'A','Â':'A'};   // you fill in the rest of the map

工作演示:http://jsfiddle.net/jfriend00/rRpcy/

仅供参考,谷歌搜索“重音折叠”会返回许多其他实现(许多类似,但也有一些使用正则表达式)。


这是一个更高性能的版本(快2.5倍),可以对重音字符进行直接索引查找,而不必进行对象查找:

function Unaccent(str) {
    var result = "", code, lookup, replaceChar;
    for (var i = 0, len = str.length; i < len; i++) {
        replaceChar = str.charAt(i);
        code = str.charCodeAt(i);
        // see if code is in our map
        if (code >= 192 && code <= 255) {
            lookup = Unaccent.map.charAt(code - 192);
            if (lookup !== ' ') {
                replaceChar = lookup;
            }
        }
        result += replaceChar;
    }
    return(result);
}

// covers chars from 192-255
// blank means no mapping for that char
Unaccent.map = "AAAAAAACEEEEIIIIDNOOOOO OUUUUY  aaaaaaaceeeeiiiionooooo  uuuuy y";

工作演示:http://jsfiddle.net/jfriend00/Jxr9u/

this jsperf中,字符串查找版本(第二个示例)的速度提高了约2.5倍。

答案 1 :(得分:1)

您可以准备键值对类型的数组,并通过jquery遍历该数组。

示例:

function Unaccent(str) {
   var replaceString = {'À':'A','Á':'A','Â':'A'}; // add more 

   $.each(replaceString, function(k, v) {
      var regX = new RegExp(k, 'g');    
      str = str.replace(regX,v);
   });
}

Working Demo

祝你好运!!

答案 2 :(得分:1)

将对象用作地图是一个好主意,但考虑到要替换的字符数,预先初始化对象可能是个好主意,这样就不必每次都重新初始化对象。函数运行(假设您运行多次函数):

var Unaccent = (function () {
    var charMap = {'À':'A','Á':'A','Â':'A','Ã':'A','Ä':'A' /** etc. **/};
    return function (str) {
        var i, modified = "", cur;
        for(i = 0; i < str.length; i++) {
            cur = str.charAt(i);
            modified += (charMap[cur] || cur);
        }
        return modified;
    };
}());

这会将函数的繁重时间加载到页面加载时间(如果您愿意,可以进行一些修改以将其延迟到第一次调用函数)。但是实际的函数调用需要一些处理时间。

有些浏览器可能会实际优化此部件,因此您可能看不到任何好处。但是对于较旧的浏览器(性能更受关注),您可能会看到预处理角色地图的一些好处。