2012-09-24 169 views
0

我需要用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; 
} 
+0

你在找什么叫做“口音折叠”。使用已经过测试的东西,而不是酝酿自己的:) – jensgram

回答

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

这将前加载功能,页面加载时间的繁重(你可以做一些修改,推迟,直到如果你喜欢的话,首先调用函数)。但是实际的函数调用需要一些处理时间。

无论如何,某些浏览器可能会实际优化此部分,因此您可能看不到任何好处。但在较旧的浏览器(性能更受关注)中,您可能会看到预处理角色映射的一些好处。

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倍。

+0

添加了新版本,速度提高2.5倍。 – jfriend00

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

好运!!