48

ユーザーがテキスト ボックスで検索する名前に、AJAX ベースのルックアップを使用しています。

私は、データベース内のすべての名前がヨーロッパのアルファベットに音訳されると仮定しています (つまり、キリル文字、日本語、中国語はありません)。ただし、名前には ç、ê、さらには č や ć などのアクセント付き文字が含まれます。

ただし、「Micic」のような単純な検索では「Mičić」とは一致しません。ユーザーは一致することを期待しています。

AJAX ルックアップでは、正規表現を使用して一致を判断します。よりアクセントのある文字に一致させるために、この関数を使用して正規表現の比較を変更しました。ただし、すべての文字を考慮していないため、少し不器用です。

function makeComp (input)
{
    input = input.toLowerCase ();
    var output = '';
    for (var i = 0; i < input.length; i ++)
    {
        if (input.charAt (i) == 'a')
            output = output + '[aàáâãäåæ]'
        else if (input.charAt (i) == 'c')
            output = output + '[cç]';
        else if (input.charAt (i) == 'e')
            output = output + '[eèéêëæ]';
        else if (input.charAt (i) == 'i')
            output = output + '[iìíîï]';
        else if (input.charAt (i) == 'n')
            output = output + '[nñ]';
        else if (input.charAt (i) == 'o')
            output = output + '[oòóôõöø]';
        else if (input.charAt (i) == 's')
            output = output + '[sß]';
        else if (input.charAt (i) == 'u')
            output = output + '[uùúûü]';
        else if (input.charAt (i) == 'y')
            output = output + '[yÿ]'
        else
            output = output + input.charAt (i);
    }
    return output;
}

このような置換関数とは別に、より良い方法はありますか? おそらく、比較されている文字列を「アクセントをなくす」ためですか?

4

8 に答える 8

16

この古いスレッドにたどり着き、高速な機能を試してみようと思いました。関数 replace() が呼び出しているときに変数が一致する場合、パイプで区切られた OR 設定変数の順序に依存しています。私の目標は、標準の正規表現実装 javascript の replace() 関数をできるだけ多く使用することでした。これにより、高価な javascript の文字ごとの比較ではなく、ブラウザに最適化された低レベルのスペースで重い処理を行うことができます。 .

まったく科学的ではありませんが、このスレッドの他の関数をオートコンプリートにプラグインすると、古い Huawei IDEOS Android フォンの動作が遅くなりますが、この関数は高速で実行されます。

function accentFold(inStr) {
  return inStr.replace(
    /([àáâãäå])|([çčć])|([èéêë])|([ìíîï])|([ñ])|([òóôõöø])|([ß])|([ùúûü])|([ÿ])|([æ])/g, 
    function (str, a, c, e, i, n, o, s, u, y, ae) {
      if (a) return 'a';
      if (c) return 'c';
      if (e) return 'e';
      if (i) return 'i';
      if (n) return 'n';
      if (o) return 'o';
      if (s) return 's';
      if (u) return 'u';
      if (y) return 'y';
      if (ae) return 'ae';
    }
  );
}

あなたが jQuery 開発者なら、この関数を使用する便利な例を次に示します。セレクターで :contains を使用するのと同じ方法で :icontains を使用できます。

jQuery.expr[':'].icontains = function (obj, index, meta, stack) {
  return accentFold(
    (obj.textContent || obj.innerText || jQuery(obj).text() || '').toLowerCase()
  )
    .indexOf(accentFold(meta[3].toLowerCase())
  ) >= 0;
};
于 2013-04-08T18:23:25.537 に答える
6

私が考えることができる「脱アクセント」する簡単な方法はありませんが、置換をもう少し合理化することができます:

var makeComp = (function(){

    var accents = {
            a: 'àáâãäåæ',
            c: 'ç',
            e: 'èéêëæ',
            i: 'ìíîï',
            n: 'ñ',
            o: 'òóôõöø',
            s: 'ß',
            u: 'ùúûü',
            y: 'ÿ'
        },
        chars = /[aceinosuy]/g;

    return function makeComp(input) {
        return input.replace(chars, function(c){
            return '[' + c + accents[c] + ']';
        });
    };

}());
于 2011-04-18T09:11:48.330 に答える
0

私はこれのプロトタイプバージョンを作りました:

String.prototype.strip = function() {
  var translate_re = /[öäüÖÄÜß ]/g;
  var translate = {
    "ä":"a", "ö":"o", "ü":"u",
    "Ä":"A", "Ö":"O", "Ü":"U",
    " ":"_", "ß":"ss"   // probably more to come
  };
    return (this.replace(translate_re, function(match){
        return translate[match];})
    );
};

次のように使用します:

var teststring = 'ä ö ü Ä Ö Ü ß';
teststring.strip();

これにより、文字列がa_o_u_A_O_U_ssに変更されます

于 2011-05-25T11:13:26.043 に答える
-3

まず、if-else if ...の長い文字列ではなく、switchステートメントをお勧めします。

それでは、なぜ現在のソリューションが気に入らないのかわかりません。それは確かに最もきれいなものです。「すべてのキャラクター」を考慮しないとはどういう意味ですか?

JavaScriptには、サードパーティのライブラリを使用する以外にアクセント付き文字をASCII文字にマップする標準的な方法がないため、作成したものは他のどの方法よりも優れています。

また、「ß」は単一の「s」ではなく「ss」にマップされると思います。また、トルコ語でドットがある場合とない場合の「i」に注意してください。これらは異なる文字を指していると思います。

于 2011-04-18T09:10:03.707 に答える