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

IT技术 javascript compare polish
2021-03-01 19:50:14

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

6个回答

您可以使用ECMAScript 国际化 API引入的Intl.CollatorString.prototype.localeCompare

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

-1意味着它Ł在之前Z,就像你想要的那样。

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

如果您必须对多语言环境单词列表进行排序。例如来自不同国家的人名列表。这行不通,不是吗?
2021-05-15 19:50:14

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

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为第三个参数以区分大小写。

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

@tchrist,这里不是 PHP,而是 javascript,就像它一样。
2021-05-03 19:50:14
oop!你真的需要经历这一切吗?忘记先放入规范化表格 D 怎么办?PHP 真的没有与 Perl 的Unicode::Collat​​eUnicode::Collat​​e::Localemodule等效的东西吗?真的吗?试图自己重新实现所有这些似乎是完全疯狂的!
2021-05-08 19:50:14
如果您正在使用此代码,另请参阅:stackoverflow.com/questions/3630645/...
2021-05-12 19:50:14

您可以使用localeCompare()来构建自己的排序功能- 至少根据关于该主题MDC 文章- 应该正确排序。

如果这不起作用,这里有一个有趣的 SO 问题,其中 OP 使用字符串替换来构建“蛮力”排序机制。

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

编辑:作为一个完全遥不可及的想法 - 我根本不知道这是否可行,尤其是出于性能方面的考虑 - 如果您无论如何都在后端使用 PHP/mySQL,我想提一下将 Ajax 查询发送到 mySQL 实例以对其进行排序。mySQL 非常擅长对区域设置感知数据进行排序,因为您可以使用例如ORDER BY xyz COLLATE utf8_polish_ci, COLLATE utf8_german_ci...

哦,我之前没看到评论。无论如何,为了避免不可预见的浏览器不一致(我仍然没有真正的感觉localeCompare()),我会像 Tomalak 在您的链接主题中那样实现一个自定义的。
2021-04-27 19:50:14
谢谢。对于链接。JavaScript 在核心中不支持它有点遗憾,但它仍然是有效的解决方案。
2021-05-09 19:50:14
2021-05-12 19:50:14
@BalusC 我同意这可能是最好和最可靠的方法。
2021-05-12 19:50:14
@BalusC 那篇文章中的评论声称这实际上是 Wine 的错,而不是 IE6 的错。找不到关于该问题的任何其他内容来确认或反驳它,而且我现在懒得构建测试用例...@Tomasz 如果你走这条路,听到事情是否正常运行会很有趣IE6。
2021-05-14 19:50:14

针对未提及的字符改进了麦克风的代码:

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]");

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

使用默认格式选项改进您的答案
2021-04-25 19:50:14
解决办法是: myArray.sort(new Intl.Collator('pl').compare);
2021-05-16 19:50:14