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

Tom*_*cki 40 javascript compare polish

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

Ori*_*iol 34

您可以使用Intl.CollatorString.prototype.localeCompareECMAScript Internationalization API引入:

"?".localeCompare("Z", "pl");              // -1
new Intl.Collator("pl").compare("?","Z");  // -1
Run Code Online (Sandbox Code Playgroud)

-1意味着?之前Z,就像你想要的那样.

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


Mic*_*Mic 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;
  };
};
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

  • @tchrist,它不是PHP,而是javascript,就像它一样. (2认同)

Pek*_*ica 13

您可以使用localeCompare()它来构建自己的排序函数- 至少根据有关该主题MDC文章 - 应该正确排序.

如果这不成功,这里有一个有趣的SO问题,其中OP使用字符串替换来构建"强力"排序机制.

同样在那个问题中,OP展示了如何为jQuery tablesorter插件构建自定义textExtract函数,该插件可以进行区域设置感知排序 - 也许值得一看.

编辑:作为一个非常遥远的想法 - 我根本不知道这是否可行,特别是因为性能问题 - 如果你在后端使用PHP/mySQL,我想提一下可能性将Ajax查询发送到mySQL实例以使其在那里排序.MySQL是在分拣现场感知的数据很大,因为你可以强制排序操作到例如使用一个特定的整理ORDER BY xyz COLLATE utf8_polish_ci,COLLATE utf8_german_ci......这些排序规则将在一次照顾所有排序的疾苦.

  • 小心 IE6 中的“localeCompare()”:http://blog.schmichael.com/2008/07/14/javascript-collat​​ion-fail/ (2认同)

Tom*_*cki 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]");
Run Code Online (Sandbox Code Playgroud)