(德语)下 ß (U+00DF) 和上 ? 之间的折写转换 (U+1E9E)?

jub*_*us1 5 string unicode unicode-string string-comparison raku

根据维基百科,2017 年,使用大写字母\xe1\xba\x9e(Unicode U+1E9E) 被正式采用——至少作为一种选择——实际上可能是德语中全大写单词的子集:

\n

同年 6 月,德国正字法委员会正式通过了一项规则,\xe2\x9f\xa8\xe1\xba\x9e\xe2\x9f\xa9 将成为 \xe2\x9f\xa8\xc3\x9f 大写的选项\xe2\x9f\xa9 除了之前的大写形式 \xe2\x9f\xa8SS\xe2\x9f\xa9 之外(即变体 STRASSE 和 STRA\xe1\xba\x9eE 将被视为同等有效)。2

\n

似乎对德语的这一补充将大大简化字符串之间的大小写比较(所谓的“大小写折叠”或“折叠大小写”比较)。注意,我开始这个询问是为了理解 Raku(又名 Perl6)的实现,但实际上这个问题似乎可以推广到其他编程语言。这是 Raku 的默认实现 - 从rfdr_Regeln_2017.pdf中的 13 个单词开始,这些单词已小写(通过 Raku 的.lc函数):

\n
~$ cat TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e.txt\nma\xc3\x9f stra\xc3\x9fe grie\xc3\x9f spie\xc3\x9f gro\xc3\x9f gr\xc3\xbc\xc3\x9fen au\xc3\x9fen au\xc3\x9fer drau\xc3\x9fen strau\xc3\x9f bei\xc3\x9fen flei\xc3\x9f hei\xc3\x9fen\n~$ raku -ne \'.words>>.match(/^ <:Ll>+ $/).say;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e.txt\n(\xef\xbd\xa2ma\xc3\x9f\xef\xbd\xa3 \xef\xbd\xa2stra\xc3\x9fe\xef\xbd\xa3 \xef\xbd\xa2grie\xc3\x9f\xef\xbd\xa3 \xef\xbd\xa2spie\xc3\x9f\xef\xbd\xa3 \xef\xbd\xa2gro\xc3\x9f\xef\xbd\xa3 \xef\xbd\xa2gr\xc3\xbc\xc3\x9fen\xef\xbd\xa3 \xef\xbd\xa2au\xc3\x9fen\xef\xbd\xa3 \xef\xbd\xa2au\xc3\x9fer\xef\xbd\xa3 \xef\xbd\xa2drau\xc3\x9fen\xef\xbd\xa3 \xef\xbd\xa2strau\xc3\x9f\xef\xbd\xa3 \xef\xbd\xa2bei\xc3\x9fen\xef\xbd\xa3 \xef\xbd\xa2flei\xc3\x9f\xef\xbd\xa3 \xef\xbd\xa2hei\xc3\x9fen\xef\xbd\xa3)\n~$ raku -ne \'.uc.say;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e.txt\nMASS STRASSE GRIESS SPIESS GROSS GR\xc3\x9cSSEN AUSSEN AUSSER DRAUSSEN STRAUSS BEISSEN FLEISS HEISSEN\n~$ raku -ne \'.fc.say;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e.txt\nmass strasse griess spiess gross gr\xc3\xbcssen aussen ausser draussen strauss beissen fleiss heissen\n
Run Code Online (Sandbox Code Playgroud)\n

我很惊讶 Raku 的fc折叠大小写实现本质上会转换为小写sseq那么尝试搜索上下“往返”单词和原始单词之间的字符串相等性就不足为奇了False

\n
~$ raku -ne \'for .words {print $_.uc.lc eq $_.lc }; "".put;\'  TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e.txt\nFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse\n
Run Code Online (Sandbox Code Playgroud)\n

折叠 ( .fc) 单词匹配,但它们是基于ss字符而不是\xc3\x9f

\n
~$ raku -ne \'for .words {print $_.uc.lc eq $_.fc }; "".put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e.txt\nTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrue\n
Run Code Online (Sandbox Code Playgroud)\n
\n

从大写-\xe1\xba\x9e 开始,只取一个大写/大写单词,再次证明了二分法:

\n
~$ echo "stra\xc3\x9fe STRASSE STRA\xe1\xba\x9eE" | raku -ne \' .put for .words;\'\nstra\xc3\x9fe\nSTRASSE\nSTRA\xe1\xba\x9eE\n~$ echo "stra\xc3\x9fe STRASSE STRA\xe1\xba\x9eE" | raku -ne \' .lc.say for .words;\'\nstra\xc3\x9fe\nstrasse\nstra\xc3\x9fe\n~$ echo "stra\xc3\x9fe STRASSE STRA\xe1\xba\x9eE" | raku -ne \' for .words { say $_.lc eq "stra\xc3\x9fe" };\'\nTrue\nFalse\nTrue\n~$ echo "stra\xc3\x9fe STRASSE STRA\xe1\xba\x9eE" | raku -ne \' for .words { say $_.lc eq $_.fc };\'\nFalse\nTrue\nFalse\n
Run Code Online (Sandbox Code Playgroud)\n

默认情况下,是否有任何编程语言foldcase在小写\xc3\x9f<--> 大写之间建立了转换\xe1\xba\x9e?哪些编程语言添加了小写\xc3\x9f<--> 大写\xe1\xba\x9e转换作为选项(或通过库)?StackOverflow 上的许多问题/答案早于 2017 年的决定,因此我正在寻找最新的答案。

\n

[附录:我通过此常见问题解答注意到 Unicode 联盟的规则似乎与德国正字法委员会 2017 年的决定不一致]。

\n

jub*_*us1 4

1. 小写/大写:

\n

在 Raku 中,从小写德语默认转换\xc3\x9f为大写SS,但这可以克服(如下所示)。

\n

Unicode 联盟针对这些德语字母有专门的常见问题解答。但是,如果想使用 Raku 解决第一个uc大写问题,"\xc3\x9f" => "\xe1\xba\x9e"可以在调用 bog 标准大写方法/函数之前trans对字符进行适当的延迟处理:uc

\n
~$ cat TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nMa\xc3\x9f Stra\xc3\x9fe Grie\xc3\x9f Spie\xc3\x9f Gro\xc3\x9f Gr\xc3\xbc\xc3\x9fen Au\xc3\x9fen Au\xc3\x9fer Drau\xc3\x9fen Strau\xc3\x9f Bei\xc3\x9fen Flei\xc3\x9f Hei\xc3\x9fen\nraku -ne \'.uc.put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nMASS STRASSE GRIESS SPIESS GROSS GR\xc3\x9cSSEN AUSSEN AUSSER DRAUSSEN STRAUSS BEISSEN FLEISS HEISSEN\n~$ raku -ne \'.trans("\xc3\x9f" => "\xe1\xba\x9e").put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nMa\xe1\xba\x9e Stra\xe1\xba\x9ee Grie\xe1\xba\x9e Spie\xe1\xba\x9e Gro\xe1\xba\x9e Gr\xc3\xbc\xe1\xba\x9een Au\xe1\xba\x9een Au\xe1\xba\x9eer Drau\xe1\xba\x9een Strau\xe1\xba\x9e Bei\xe1\xba\x9een Flei\xe1\xba\x9e Hei\xe1\xba\x9een\n~$ raku -ne \'.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nMA\xe1\xba\x9e STRA\xe1\xba\x9eE GRIE\xe1\xba\x9e SPIE\xe1\xba\x9e GRO\xe1\xba\x9e GR\xc3\x9c\xe1\xba\x9eEN AU\xe1\xba\x9eEN AU\xe1\xba\x9eER DRAU\xe1\xba\x9eEN STRAU\xe1\xba\x9e BEI\xe1\xba\x9eEN FLEI\xe1\xba\x9e HEI\xe1\xba\x9eEN\n
Run Code Online (Sandbox Code Playgroud)\n

上面的代码适用于大写文本,而\xe1\xba\x9e不是SS- 并且本着真正的 Raku/Perl 精神 - 有不止一种方法可以做到这一点(TMTOWTDI):

\n
~$ raku -ne \'.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.put;\' file\n~$ raku -e \'.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.put for lines();\' file\n~$ raku -e \'put .trans("\xc3\x9f" => "\xe1\xba\x9e").uc for lines();\' file\n~$ raku -e \'slurp.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.put;\' file\n~$ raku -e \'slurp.trans( "\\x[00DF]" => "\\x[1E9E]" ).uc.put;\' file\n~$ raku -e \'slurp.trans("LATIN SMALL LETTER SHARP S".uniparse => "LATIN CAPITAL LETTER SHARP S".uniparse).uc.put;\' file\n
Run Code Online (Sandbox Code Playgroud)\n
\n

2. 折叠盒:

\n

Unicode 联盟颁布了一项规则,即折叠大小写对应该稳定(根据Unicode 大小写折叠稳定性政策)。

\n

至于fc折叠盒的稳定性,我希望之前的转换"\xc3\x9f" => "\xe1\xba\x9e"能够提供一个“第 30 个大写字符”,该字符将充当小写字母的两院折叠盒伙伴\xc3\x9f(成对)。下面的代码似乎很有前途,因为从一小部分混合大小写文本开始,您可以从大写到小写“往返”,并且仍然具有与小写匹配的输出文本:

\n
~$ raku -ne \'for .words {print $_.uc.lc eq $_.lc }; "".put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse\n~$ raku -ne \'for .words {print $_.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.lc eq $_.lc }; "".put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrue\n
Run Code Online (Sandbox Code Playgroud)\n

但是,fc下面的 Foldcase 代码显示当前的操作过程是采用大写字母\xe1\xba\x9e并转换为小写字母ss(而不是转换为 lowercase \xc3\x9f)。本质上.fc,foldcase 会将大写\xe1\xba\x9e或小写转换SS为小写ss,无论:

\n
~$ raku -ne \'.trans("\xc3\x9f" => "\xe1\xba\x9e").fc.put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nmass strasse griess spiess gross gr\xc3\xbcssen aussen ausser draussen strauss beissen fleiss heissen\n~$ raku -ne \'for .words {print $_.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.fc eq $_.fc }; "".put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrue\n~$ raku -ne \'for .words {print $_.trans("\xc3\x9f" => "\xe1\xba\x9e").uc.lc eq $_.fc }; "".put;\' TO_\xe1\xba\x9e_OR_NOT_TO_\xe1\xba\x9e_tclc.txt\nFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse\n
Run Code Online (Sandbox Code Playgroud)\n

预期的变化?根据 2017 年 StackOverflow 的一篇文章,“再等半个世纪吧。

\n

https://raku.org

\n