如何在Javascript中比较Unicode字符串?

时间:2010-09-02 19:47:08

标签: javascript compare polish

当我用JavaScript "Ł" > "Z"写作时,它会返回true。在Unicode顺序中,它当然应该是false。如何解决这个问题?我的网站使用的是UTF-8。

6 个答案:

答案 0 :(得分:31)

您可以使用Intl.Collator引入的String.prototype.localeCompareECMAScript Internationalization API

"Ł".localeCompare("Z", "pl");              // -1
new Intl.Collator("pl").compare("Ł","Z");  // -1

-1表示Ł出现在Z之前,就像您想要的那样。

请注意,它仅适用于最新的浏览器。

答案 1 :(得分:19)

以下是法语字母表的示例,可以帮助您进行自定义排序:

var alpha = function(alphabet, dir, caseSensitive){
  return function(a, b){
    var pos = 0,
      min = Math.min(a.length, b.length);
    dir = dir || 1;
    caseSensitive = caseSensitive || false;
    if(!caseSensitive){
      a = a.toLowerCase();
      b = b.toLowerCase();
    }
    while(a.charAt(pos) === b.charAt(pos) && pos < min){ pos++; }
    return alphabet.indexOf(a.charAt(pos)) > alphabet.indexOf(b.charAt(pos)) ?
      dir:-dir;
  };
};

在字符串数组a上使用它:

a.sort(
  alpha('ABCDEFGHIJKLMNOPQRSTUVWXYZaàâäbcçdeéèêëfghiïîjklmnñoôöpqrstuûüvwxyÿz')
);

添加1-1作为alpha()的第二个参数,以升序或降序排序。
添加true作为第3个参数,以区分区分大小写。

您可能需要在字母表列表中添加数字和特殊字符

答案 2 :(得分:13)

您可以使用localeCompare()构建自己的排序函数 - 至少根据MDC article on the topic - 应该正确排序。

如果这不成功,这里有一个interesting SO question,其中OP使用字符串替换来构建“强力”排序机制。

同样在那个问题中,OP展示了如何为进行区域设置感知排序的jQuery tablesorter插件构建a custom textExtract function - 也许值得一看。

编辑:作为一个完全不为人知的想法 - 我根本不知道这是否可行,特别是因为性能问题 - 如果你在后端使用PHP / mySQL无论如何,我想提一下将一个Ajax查询发送到mySQL实例以使其在那里排序的可能性。 mySQL非常善于对区域设置感知数据进行排序,因为您可以使用例如强制排序操作强制进行特定的排序操作。 ORDER BY xyz COLLATE utf8_polish_ciCOLLATE utf8_german_ci ......这些排序系统会立即解决所有排序问题。

答案 3 :(得分:9)

Mic的代码针对未提及的字符进行了改进:

var alpha = function(alphabet, dir, caseSensitive){
  dir = dir || 1;
  function compareLetters(a, b) {
    var ia = alphabet.indexOf(a);
    var ib = alphabet.indexOf(b);
    if(ia === -1 || ib === -1) {
      if(ib !== -1)
        return a > 'a';
      if(ia !== -1)
        return 'a' > b;
      return a > b;
    }
    return ia > ib;
  }
  return function(a, b){
    var pos = 0;
    var min = Math.min(a.length, b.length);
    caseSensitive = caseSensitive || false;
    if(!caseSensitive){
      a = a.toLowerCase();
      b = b.toLowerCase();
    }
    while(a.charAt(pos) === b.charAt(pos) && pos < min){ pos++; }
    return compareLetters(a.charAt(pos), b.charAt(pos)) ? dir:-dir;
  };
};

function assert(bCondition, sErrorMessage) {
      if (!bCondition) {
          throw new Error(sErrorMessage);
      }
}

assert(alpha("bac")("a", "b") === 1, "b is first than a");
assert(alpha("abc")("ac", "a") === 1, "shorter string is first than longer string");
assert(alpha("abc")("1abc", "0abc") === 1, "non-mentioned chars are compared as normal");
assert(alpha("abc")("0abc", "1abc") === -1, "non-mentioned chars are compared as normal [2]");
assert(alpha("abc")("0abc", "bbc") === -1, "non-mentioned chars are compared with mentioned chars in special way");
assert(alpha("abc")("zabc", "abc") === 1, "non-mentioned chars are compared with mentioned chars in special way [2]");

答案 4 :(得分:0)

您必须保留两个sortkey字符串。一个用于一级,其中德语ä= a(主要a-> a)和法语é= e(主要排序键e-> e),另一个用于二级,其中ä后面是a(在二级中翻译a-> azzzz键)或é在e之后(辅助键e-> zzzzzz)。特别是在捷克语中,某些字母是字母的变体(áéí…),而其他字母则完全位于列表中(ABCČD…GHChI…RŘSŠT…)。加上将有向图考虑为单个字母的问题(主要ch-> hzzzz)。没有什么小问题,并且在JS中应该有解决方案。

答案 5 :(得分:-1)

好笑,我必须考虑这个问题,并在这里完成搜索,因为它记住了,我可以使用自己的javascript模块。我写了一个模块来生成一个干净的URL,因此我必须对输入字符串进行转换...(http://pid.github.io/speakingurl/

var mySlug = require('speakingurl').createSlug({
    maintainCase: true,
    separator: " "
});

var input = "Schöner Titel läßt grüßen!? Bel été !";
var result;

slug = mySlug(input);
console.log(result); // Output: "Schoener Titel laesst gruessen bel ete"

现在您可以使用此结果进行排序。你可以前。将原始标题存储在“title”字段中,将字段存储在“title_sort”中,并附带mySlug的结果。