【问题标题】:How to iterate over over all Unicode characters?如何遍历所有 Unicode 字符?
【发布时间】:2016-02-20 21:31:03
【问题描述】:

是否可以遍历所有 Unicode 字符 (UTF-8)?谢谢! 我试过使用:

character = String.fromCharCode(i);

但我不确定如何实现它。

【问题讨论】:

  • 把它放到一个for循环中,遍历i的所有可能值。
  • 那么对于charcode,那是什么格式? x\00000 之类的东西?
  • 这就是将其写为文字字符串的格式。但你不需要这样做,fromCharCode() 返回字符。
  • 说起来容易做起来难@Barmar,我来寻找可能值的限制和迭代的格式(十进制、十六进制等)。

标签: javascript unicode iteration


【解决方案1】:

Javascript 字符串有一个长度属性。您可以简单地遍历字符:

for(var i = 0; i < str.length; i++) {
    var char = str[i],
       code = str.charCodeAt(i);
}

【讨论】:

  • 这个答案不正确。此代码迭代 16 位“字符”,即使其中 2 个构成代理对并因此表示一个字符。以'?'.length 为例。
【解决方案2】:

根据to the docs,将传递给String.fromCharCode(a)的参数转换为调用ToUint16,然后返回所述字符。你可以用你想要的任何数字来调用它,但值将被限制在 0 和 216 或 232

之间
highNumber = 500; //This could go very high
out = ""
for(i=0;i<highNumber;i++){
    out += String.fromCharCode(i);
}
console.log(out);

危险提示如果您使用2^16运行此代码,您可能会冻结您的标签或浏览器,它太大了。这是理解您想要迭代 所有字符 而不是 给定字符串 中的所有字符,这是完全不同的事情。

更合理的highNumber(即500)的示例输出如下:

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqr
stuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæç
èéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺ
ĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍ
ƎƏƐƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠ
ǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdz

【讨论】:

  • 只是一个观察,问题只是关于迭代,没有必要构建一个包含所有可能字符的新字符串。例如,我来这里寻找 charcode 值的最大限制。我计划循环并仅比较。内存问题不应该适用。
【解决方案3】:

UTF-8 是一种编码! JavaScript 字符串以 UTF-16 编码 (mostly)。只有在不支持 ES6 的 String.fromCodePoint 的环境中工作时,编码才重要。使用 ES6 从代码点获取字符串:

var s = String.fromCodePoint(codePoint);

在没有 ES6 的情况下,对 U+10000 及以后的字符使用 UTF-16 surrogate pair

var s;

if (codePoint < 0x10000) {
    s = String.fromCharCode(codePoint);
} else {
    var offset = codePoint - 0x10000;
    s = String.fromCharCode(0xd800 + (offset >> 10),
                            0xdc00 + (offset & 0x3ff));
}

代码点的范围从 U+0000 到 U+10FFFF(1 114 112 值),但并非该范围内的所有字符都是有效的 Unicode 字符。您可以从http://www.unicode.org/Public/8.0.0/ucd/UnicodeData.txt 获取一个表格并提取您真正想要迭代的字符。

【讨论】:

    【解决方案4】:

    我认为这可能会准确定义要迭代的内容:

    【讨论】:

    • 很抱歉投反对票,这在技术上是正确的,但太低级了!
    【解决方案5】:

    (添加此答案是因为与某些 Google 搜索相关)

    在可能包含 UTF-8 多码位字符(即表情符号或非拉丁字母)的字符串上逐个字符迭代的正确方法是 Array.from()

    const bugs = '???'
    
    // WRONG, does not account for characters with > 2 Unicode code points
    bugs.split('')
    // Array(6) [ "\ud83d", "\udc1b", "\ud83d", "\udc1b", "\ud83d", "\udc1b" ]
    
    // CORRECT
    Array.from(bugs)
    // Array(3) [ "?", "?", "?" ]
    

    然后,像迭代任何普通数组一样进行迭代(建议:map/forEach)。

    更多信息:https://medium.com/@giltayar/iterating-over-emoji-characters-the-es6-way-f06e4589516

    【讨论】:

      猜你喜欢
      • 2023-02-21
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-19
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多