如何在javascript中使用表情符号计算字符串的正确长度?

如何在javascript中使用表情符号计算字符串的正确长度?,javascript,node.js,emoji,Javascript,Node.js,Emoji,我有个小问题 我使用NodeJS作为后端。现在,用户有一个字段“传记”,用户可以在其中写一些关于自己的东西 假设此字段具有220 maxlength,并假设此字段为输入: str.length gives the count of UTF-16 units. Unicode-proof way to get string length in codepoints (in characters) is [...str].length as iterable protocol splits th

我有个小问题

我使用NodeJS作为后端。现在,用户有一个字段“传记”,用户可以在其中写一些关于自己的东西

假设此字段具有220 maxlength,并假设此字段为输入:

  1. str.length
    gives the count of UTF-16 units.

  2. Unicode-proof way to get string length in codepoints (in characters) is
    [...str].length
    as iterable protocol splits the string to codepoints.

  3. If we need the length in graphemes (grapheme clusters), we have these native ways:

    a. Unicode property escapes in RegExp. See for example: Unicode-aware version of \w or Matching emoji.

    b. Intl.Segmenter — coming soon, probably in ES2021. Can be tested with a flag in the last V8 versions (realization was synced with the last spec in V8 86). Unflagged (shipped) in V8 87.

See also:

As you can see from the below example, this is to do with unicode encoding,

There's some great resources such as the one I took this example from.

https://blog.jonnew.com/posts/poo-dot-length-equals-two

console.log("
function fancyCount2(str){
  const joiner = "\u{200D}";
  const split = str.split(joiner);
  let count = 0;

  for(const s of split){
    //removing the variation selectors
    const num = Array.from(s.split(/[\ufe00-\ufe0f]/).join("")).length;
    count += num;
  }

  //assuming the joiners are used appropriately
  return count / split.length;
}

  • str.length
    给出UTF-16单元的计数

  • Unicode验证获取码点(字符)中字符串长度的方法是
    […str].length
    ,因为iterable协议将字符串拆分为码点

  • 如果我们需要grapheme(grapheme群集)中的长度,我们有以下本机方法:

    a。在RegExp中转义Unicode属性。参见示例:或

    b、 -很快就会到来,可能在ES2021年。可以使用上一个V8版本中的标志进行测试(实现与V8 86中的上一个规范同步)。V8 87中未封装(已装运)

  • 另见:

  • str.length
    给出UTF-16单元的计数

  • Unicode验证获取码点(字符)中字符串长度的方法是
    […str].length
    ,因为iterable协议将字符串拆分为码点

  • 如果我们需要grapheme(grapheme群集)中的长度,我们有以下本机方法:

    a。在RegExp中转义Unicode属性。参见示例:或

    b、 -很快就会到来,可能在ES2021年。可以使用上一个V8版本中的标志进行测试(实现与V8 86中的上一个规范同步)。V8 87中未封装(已装运)

  • 另见:


    从下面的示例中可以看出,这与unicode编码有关

    有一些很棒的资源,比如我从中获取这个例子的资源


    console.log(“从下面的示例中可以看到,这与unicode编码有关

    Array.from(str)
    
    有一些很棒的资源,比如我从中获取这个例子的资源


    console.log(“TL;DR”)有一些解决方案,但它们并不适用于所有情况。Unicode可能感觉像一门黑暗的艺术

    Array.from(str)
    

    在我所看到的各种解决方案中似乎有局限性,问题超出了表情符号并覆盖了Unicode范围内的其他字符。如果使用,EE可以被存储为EE或E+’。这甚至可以导致看起来相同的两个字符串。注意,在某些情况下,当存储时单个表情符号可以是11个字符。结果是22个字节,假设UTF16

    处理这种情况的方式以及字符的组合或显示方式甚至可能因浏览器和操作系统而异。因此,尽管您可能认为自己破解了它,但另一个环境可能会破坏它。请务必测试它的重要性

    现在,出现了前端与后端的问题:您解决了字符数问题,因此它对人类用户非常有效,现在您的单个表情符号正好超过了数据库中分配的字段大小。对于mongo这样的数据库,问题较少,但对于SQL数据库,字段分配是保守的。这意味着您如何解决你的问题将取决于最难的限制在哪里

    请注意,基本解决方案确实涉及将字符串转换为数组并获取长度,同时接受以下限制:

    当角色组合并处理时,这将崩溃

    考虑到局限性的一些高级方法:

    • 使用尽可能最好地解决前端问题的方法,然后确保存储问题得到解决
    • 如果数据库或其他存储无法调整,请对公布的前端限制更加保守
    • 限制可以输入的字符类型
    • 明确指出长度计算的限制
    此外,考虑到问题的复杂性,可能值得一看是否有一个流行的JS库已经处理了这个问题?在撰写本文时,我没有找到一个。希望这在某种程度上成为Javascript的核心

    其他页面如下:


    TL;DR有解决方案,但它们并不适用于所有情况。Unicode可能感觉像一门黑暗的艺术

    在我所看到的各种解决方案中似乎有局限性,问题超出了表情符号并覆盖了Unicode范围内的其他字符。如果使用,EE可以被存储为EE或E+’。这甚至可以导致看起来相同的两个字符串。注意,在某些情况下,当存储时单个表情符号可以是11个字符。结果是22个字节,假设UTF16

    处理这种情况的方式以及字符的组合或显示方式甚至可能因浏览器和操作系统而异。因此,尽管您可能认为自己破解了它,但另一个环境可能会破坏它。请务必测试它的重要性

    现在,出现了前端与后端的问题:您解决了字符数问题,因此它对人类用户非常有效,现在您的单个表情符号正好超过了数据库中分配的字段大小。对于mongo这样的数据库,问题较少,但对于SQL数据库,字段分配是保守的。这意味着您如何解决你的问题将取决于最难的限制在哪里

    请注意,基本解决方案确实涉及将字符串转换为数组并获取长度,同时接受以下限制:

    当角色组合并处理时,这将崩溃

    考虑到局限性的一些高级方法:

    • 使用尽可能最好地解决前端问题的方法,然后确保存储问题得到解决
    • 如果数据库或o