2012-09-24 164 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

好運!!