Java 如何确定一系列代码点是否构成自然字符?

Java 如何确定一系列代码点是否构成自然字符?,java,language-agnostic,unicode,Java,Language Agnostic,Unicode,大家下午好 我正在构建一个函数,该函数将字符串作为输入,从字符串中删除任何不自然的组合变音字符,并将修改后的字符串作为输入返回 非自然组合变音序列是unicode代码点的序列,当组合时,产生的输出不属于任何自然语言(古代脚本/语言被视为自然语言) 例如,给定字符串输入: "aaà̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̯̰̱̲̳̹̺̻̼͇͈͉͍͎́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚͠͡ͅaa" //code points 0061 00

大家下午好

我正在构建一个函数,该函数将字符串作为输入,从字符串中删除任何不自然的组合变音字符,并将修改后的字符串作为输入返回

非自然组合变音序列是unicode代码点的序列,当组合时,产生的输出不属于任何自然语言(古代脚本/语言被视为自然语言)

例如,给定字符串输入:

   "aaà̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̯̰̱̲̳̹̺̻̼͇͈͉͍͎́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚͠͡ͅaa" //code points 0061 0061 0061 0300 0301 0302 0303 0304 0305 0306 0307 0308 0309 030a 030b 030c 030d 030e 030f 0310 0311 0312 0313 0314 0315 0316 0317 0318 0319 031a 031b 031c 031d 031e 031f 0320 0321 0322 0323 0324 0325 0326 0327 0328 0329 032a 032b 032c 032d 032e 032f 032f 0330 0331 0332 0333 0334 0335 0336 0337 0338 0339 033a 033b 033c 033d 033e 033f 0340 0341 0342 0343 0344 0345 0346 0347 0348 0349 034a 034b 034c 034d 034e 0360 0361 0061 0061
,函数应返回结果
aaáaa
(代码点0061 0061 0061 0300 0061 0061)

因为(代码点0061 0300 0301)在任何自然语言中都不是字符。换言之:

  assert F("aaà̴̵̶̷̸̡̢̧̨̛̖̗̘̙̜̝̞̟̠̣̤̥̦̩̪̫̬̭̮̯̯̰̱̲̳̹̺̻̼͇͈͉͍͎́̂̃̄̅̆̇̈̉̊̋̌̍̎̏̐̑̒̓̔̽̾̿̀́͂̓̈́͆͊͋͌̕̚͠͡ͅaa").equals("aaàaa");
或对于使用拉丁字符集保存的源代码:

 assert F("\u0061\u0061\u0061\u0300\u0301\u0302\u0303\u0304\u0305\u0306\u0307\u0308\u0309\u030a\u030b\u030c\u030d\u030e\u030f\u0310\u0311\u0312\u0313\u0314\u0315\u0316\u0317\u0318\u0319\u031a\u031b\u031c\u031d\u031e\u031f\u0320\u0321\u0322\u0323\u0324\u0325\u0326\u0327\u0328\u0329\u032a\u032b\u032c\u032d\u032e\u032f\u032f\u0330\u0331\u0332\u0333\u0334\u0335\u0336\u0337\u0338\u0339\u033a\u033b\u033c\u033d\u033e\u033f\u0340\u0341\u0342\u0343\u0344\u0345\u0346\u0347\u0348\u0349\u034a\u034b\u034c\u034d\u034e\u0360\u0361\u0061\u0061").equals("\u0061\u0061\u0061\u0300\u0061\u0061");
我们如何确定字符序列或unicode码点序列是自然的


或者更确切地说,属于自然语言的字符将使用多少组合变音字符有限制吗?

我认为您只需要
character.isleter()
。我刚刚用英语、俄语和希伯来语字符进行了尝试,它对所有字母返回
true
,对所有非字母的字符返回false

我不知道像“.”、“.”、等这样的字符是否是自然字符,但如果需要,您可以轻松地枚举所有这些字符。

:

所有组合字符都可以应用于任何基本字符,原则上可以使用 任何脚本。与其他字符一样,将组合字符分配给一个字符 块或其他块仅标识其主要用途;其目的不是定义或限制 可以应用它的字符范围。在Unicode标准中,所有 允许使用字符代码

这并不要求实现支持所有可能的组合 同样好。因此,在将阿拉伯语注释标记应用于汉字时 如果允许使用Devanagari辅音,则不太可能在呈现时得到很好的支持 或者说有意义

中不太可能有足够的信息来通过算法实现这一点

对于canonical,有一些规则可用于确定序列是否为“自然”序列。例如,将U+0065U+0301映射到U+00E9(é),但这并不适用于所有情况

除此之外,如果不使用由专家构建的某种形式的验证表或从一些语言数据语料库生成的验证表,我不确定您能做些什么

一个非自然的组合变音序列是一个unicode代码点序列,当组合起来时,会产生不属于任何语言的输出

如果你不懂世界上所有的语言,恐怕你就不能满足这个要求

仅使用标准Unicode数据集可以做的最接近的事情是将标准化为NFKC,并查看是否还有任何分解的组合类字符。这并没有告诉你任何关于自然语言的事情,它只依赖于一种启发,即可能会有一个为常用组合定义的组合字符。这对于最常见的简单字母表来说是正确的,这对你来说已经足够了

属于自然语言的字符使用多少组合变音字符有限制吗

否。在“流安全”文本中规定了一个实际限制,即不得使用30个连续的组合字符,这将允许我们推测Unicode标准通常会试图避免字符定义,这将导致实际语言用例中出现如此多的连续连接符

据我所知,最长的自然石墨烯簇是:

ཧྐྵྨླྺྼྻྂ

(一个初始字符和八个非空格标记。)

此方法不适用于代理项对。字符类文档中有更多信息:编辑:也就是说,这种方法只适用于基本多语言平面中的字符。@AlexR抱歉,我不想显得粗鲁,但这根本不起作用。我需要的是使用分解字符和Character.isleter不能使用分解字符。在Python中:
'.join(regex.findall(ur“\X”,unicodedata.normalize('NFKC',s))
适用于您的情况
\X
匹配一个单一的图形。是的,这就是我所说的,你知道这些表中有没有?Pacerier-我没有发现任何表。你的意思是说不可能创建函数F()?@Pacerier-没有,只是我缺乏提供解决方案的知识——我对语言学的了解不够。Unicode联盟不应该是一个拥有“阳光下所有语言”知识的联盟吗?他们有什么我们可以利用的功能(如问题中所列)吗?