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;
}
4

3 に答える 3

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/

参考までに、Googleで「アクセントフォールディング」を検索すると、他の多くの実装が返されます(多くは類似していますが、正規表現を使用しているものもあります)。


これは、オブジェクトルックアップを実行する必要がなく、アクセント付き文字の直接インデックスルックアップを実行できる少し高性能なバージョン(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/

このjsperfでは、文字列ルックアップバージョン(2番目の例)は約2.5倍高速です。

于 2012-09-24T16:25:41.973 に答える
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);
   });
}

作業デモ

幸運を !!

于 2012-09-24T16:37:14.207 に答える
1

オブジェクトをマップとして使用することは良い考えですが、置き換える文字の数を考えると、関数が取得するたびにオブジェクトを再初期化する必要がないように、オブジェクトを事前に初期化することをお勧めします。 run(関数を複数回実行していると仮定):

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

これにより、関数の重いリフティングがページの読み込み時間にフロントロードされます(必要に応じて、関数を最初に呼び出すまで遅延させるためにいくつかの変更を行うことができます)。ただし、実際の関数呼び出しからは処理時間がいくらかかかります。

一部のブラウザは実際にこの部分を最適化する可能性があるため、メリットが見られない場合があります。ただし、古いブラウザ(パフォーマンスがより重要な場合)では、文字コード表を前処理することでいくつかの利点が得られる可能性があります。

于 2012-09-24T16:38:07.097 に答える