Tia*_*ica 14 javascript string unicode normalization
在回顾 JavaScript 概念时,我发现String.normalize(). 这并没有出现在 W3School 的“ JavaScript String Reference ”中,因此,这就是我之前可能错过的原因。
我在HackerRank中找到了更多有关它的信息,其中指出:
返回一个字符串,其中包含调用字符串值的 Unicode 规范化形式。
举个例子:
var s = "HackerRank";
console.log(s.normalize());
console.log(s.normalize("NFKC"));
Run Code Online (Sandbox Code Playgroud)
具有作为输出:
HackerRank
HackerRank
Run Code Online (Sandbox Code Playgroud)
另外,在GeeksForGeeks中:
string.normalize() 是 javascript 中的内置函数,用于返回给定输入字符串的 Unicode 规范化形式。
举个例子:
<script>
// Taking a string as input.
var a = "GeeksForGeeks";
// calling normalize function.
b = a.normalize('NFC')
c = a.normalize('NFD')
d = a.normalize('NFKC')
e = a.normalize('NFKD')
// Printing normalised form.
document.write(b +"<br>");
document.write(c +"<br>");
document.write(d +"<br>");
document.write(e);
</script>
Run Code Online (Sandbox Code Playgroud)
具有作为输出:
GeeksForGeeks
GeeksForGeeks
GeeksForGeeks
GeeksForGeeks
Run Code Online (Sandbox Code Playgroud)
也许给出的例子真的很糟糕,因为它们不允许我看到任何变化。
我想知道......这个方法有什么意义?
如MDN 文档中所述,String.prototype.normalize()返回字符串的 Unicode 规范化形式。这是因为在 Unicode 中,某些字符可以有不同的表示形式。
这是示例(取自 MDN):
\nconst name1 = \'\\u0041\\u006d\\u00e9\\u006c\\u0069\\u0065\';\nconst name2 = \'\\u0041\\u006d\\u0065\\u0301\\u006c\\u0069\\u0065\';\n\nconsole.log(`${name1}, ${name2}`);\n// expected output: "Am\xc3\xa9lie, Am\xc3\xa9lie"\nconsole.log(name1 === name2);\n// expected output: false\nconsole.log(name1.length === name2.length);\n// expected output: false\n\nconst name1NFC = name1.normalize(\'NFC\');\nconst name2NFC = name2.normalize(\'NFC\');\n\nconsole.log(`${name1NFC}, ${name2NFC}`);\n// expected output: "Am\xc3\xa9lie, Am\xc3\xa9lie"\nconsole.log(name1NFC === name2NFC);\n// expected output: true\nconsole.log(name1NFC.length === name2NFC.length);\n// expected output: trueRun Code Online (Sandbox Code Playgroud)\r\n正如您所看到的,字符串Am\xc3\xa9lie有两种不同的 Unicode 表示形式。通过规范化,我们可以将两种形式简化为同一个字符串。
\n这取决于如何处理字符串:通常您不需要它(如果您只是从用户那里获取输入并将其传递给用户)。但要检查/搜索/用作密钥/等等。对于这样的字符串,您可能需要一种独特的方式来识别相同的字符串(从语义上来说)。
\n主要问题是,您可能有两个语义相同的字符串,但具有两种不同的表示形式:例如,一个带有重音字符[一个代码点],另一个带有与重音组合的字符[一个字符的代码点,一个字符用于组合重音]。用户可能无法控制输入文本的发送方式,因此您可能有两个不同的用户名或两个不同的密码。但如果你修改数据,你可能会得到不同的结果,具体取决于初始字符串。用户不喜欢它。
\n另一个问题是关于组合字符的唯一顺序。您可能有重音和较低的尾部(例如变音符号):您可以用几种组合来表达:“纯字符,尾部,重音”,“纯字符,重音,尾部”,“字符+尾部,重音”,“字符+重音符号,变音符号”。
\n并且您可能会遇到退化情况(特别是如果您从键盘输入):您可能会得到应该删除的代码点(您可能有一个无限长的字符串,它可能相当于几个字节。
\n无论如何,为了对字符串进行排序,您(或您的库)需要标准化形式:如果您已经提供了正确的形式,则库将不需要再次转换它。
\n所以:您希望相同的(从语义上讲)字符串具有相同的 unicode 代码点序列。
\n注意:如果您直接在 UTF-8 上进行操作,您还应该关心 UTF-8 的特殊情况:相同的代码点可以用不同的方式编写[使用更多字节]。这也可能是一个安全问题。
\n通常K用于“搜索”和类似任务:CO2 和 CO\xe2\x82\x82 将以相同的方式解释,但这可能会改变文本的含义,因此它通常应仅在内部用于临时任务,但保留原文。