如何在德语中将小写ß(U+00DF)和大写ẞ(U+1E9E)进行大小写转换?

5
根据维基百科,在2017年,使用大写字母(Unicode U+1E9E)被正式采用——至少作为德语中全大写单词的子集的一个选项: < p > < em > 在那一年的6月,德语正字法委员会正式通过了一项规定,即⟨ẞ⟩将成为除先前的⟨SS⟩外的另一种大写⟨ß⟩的选项(即变体STRASSE和STRAẞE将被视为同样有效)。2

看起来,德语中的这种补充将极大地简化字符串之间的大小写比较(所谓的“折叠大小写”或“折叠大小写”比较)。请注意,我开始这个调查是为了理解Raku(又名Perl6)的实现,但实际上这个问题似乎适用于其他编程语言。这是Raku的默认实现-从rfdr_Regeln_2017.pdf开始,已经通过Raku的.lc函数转换为小写的13个单词:

~$ cat TO_ẞ_OR_NOT_TO_ẞ.txt
maß straße grieß spieß groß grüßen außen außer draußen strauß beißen fleiß heißen
~$ raku -ne '.words>>.match(/^ <:Ll>+ $/).say;' TO_ẞ_OR_NOT_TO_ẞ.txt
(「maß」 「straße」 「grieß」 「spieß」 「groß」 「grüßen」 「außen」 「außer」 「draußen」 「strauß」 「beißen」 「fleiß」 「heißen」)
~$ raku -ne '.uc.say;' TO_ẞ_OR_NOT_TO_ẞ.txt
MASS STRASSE GRIESS SPIESS GROSS GRÜSSEN AUSSEN AUSSER DRAUSSEN STRAUSS BEISSEN FLEISS HEISSEN
~$ raku -ne '.fc.say;' TO_ẞ_OR_NOT_TO_ẞ.txt
mass strasse griess spiess gross grüssen aussen ausser draussen strauss beissen fleiss heissen

我很惊讶Raku的fc折叠实现基本上转换为小写ss。那么尝试在大小写“round-tripped”单词和原始单词之间搜索eq字符串相等性,则所有结果都为False
~$ raku -ne 'for .words {print $_.uc.lc eq $_.lc }; "".put;'  TO_ẞ_OR_NOT_TO_ẞ.txt
FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse

折叠大小写(.fc)单词匹配,但是基于ss字符而不是ß

~$ raku -ne 'for .words {print $_.uc.lc eq $_.fc }; "".put;' TO_ẞ_OR_NOT_TO_ẞ.txt
TrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrue

从一个大写的ẞ开始,再次只取一个大写单词就展示了二分法:

~$ echo "straße STRASSE STRAẞE" | raku -ne ' .put for .words;'
straße
STRASSE
STRAẞE
~$ echo "straße STRASSE STRAẞE" | raku -ne ' .lc.say for .words;'
straße
strasse
straße
~$ echo "straße STRASSE STRAẞE" | raku -ne ' for .words { say $_.lc eq "straße" };'
True
False
True
~$ echo "straße STRASSE STRAẞE" | raku -ne ' for .words { say $_.lc eq $_.fc };'
False
True
False

有哪些编程语言默认实现了小写 ß <--> 大写 foldcase 转换?哪些编程语言通过选项(或库)添加了小写 ß <--> 大写 转换?许多 StackOverflow 上的问题/答案都早于 2017 年的决定,因此我正在寻找最新的答案。

[补充说明:我注意到通过这个 FAQ,Unicode 协会的规则似乎与德语正字法委员会在 2017 年的决定不一致]。


3
这是我一年前在 Reddit 上写的有关 决定与编程语言、其实现和 MoarVM 的评论。 - raiph
2
列出具有特性X的编程语言不是一个合法的SO问题。 - n. m.
1
Raku的fc fold-case实现基本上会将字符串转换为小写ss。这种映射是由Unicode(正如您在上面的评论中链接的数据文件)所规定的,而且有很好的原因。为什么Raku(或任何其他语言)要做一些非标准的事情呢?它能解决什么样的问题呢? - n. m.
3
所以这里确实有一个问题——“如何以编程方式处理它?”那为什么不直接问这个问题呢?答案取决于你所说的“它”的含义。如果你想要一个可以进行大小写折叠比较字符串的程序,那么请遵循Unicode。如果你想要一个能够根据德语拼写规则正确地在全大写和正常大小写之间翻转德语单词的程序,那么最好现在就开始训练你的大型语言模型,因为你必须理解德语单词在上下文中的含义才能做到这一点。 - n. m.
3
从链接的常见问题解答中可以得知:“由于[Unicode]大小写折叠规则不因语言或上下文而异,这使它们不适合作为显示或转换人类可读文本的基础。” Unicode大小写折叠并不旨在匹配所有语言的大小写规则。实际上,它是无法做到这一点的。在某些语言中,大写字母“I”并不是小写字母“i”的大写形式。 - Raymond Chen
显示剩余6条评论
1个回答

4

1. 大小写:

Raku 中,将德语小写字母 ß 转换为大写字母 SS 是默认设置,但是可以通过以下方法克服这个问题。

Unicode 联盟在德语中有一个特殊的FAQ,涉及这些字母。然而,如果想要在 Raku 中解决第一个 uc 大写问题,可以在调用标准的 uc 大写方法/函数之前适当地使用 "ß" => "ẞ" 字符进行 translation:

~$ cat TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
Maß Straße Grieß Spieß Groß Grüßen Außen Außer Draußen Strauß Beißen Fleiß Heißen
raku -ne '.uc.put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
MASS STRASSE GRIESS SPIESS GROSS GRÜSSEN AUSSEN AUSSER DRAUSSEN STRAUSS BEISSEN FLEISS HEISSEN
~$ raku -ne '.trans("ß" => "ẞ").put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
Maẞ Straẞe Grieẞ Spieẞ Groẞ Grüẞen Auẞen Auẞer Drauẞen Strauẞ Beiẞen Fleiẞ Heiẞen
~$ raku -ne '.trans("ß" => "ẞ").uc.put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
MAẞ STRAẞE GRIEẞ SPIEẞ GROẞ GRÜẞEN AUẞEN AUẞER DRAUẞEN STRAUẞ BEIẞEN FLEIẞ HEIẞEN

上面的代码可以将带有 的文本转换为大写,而不是 SS。在真正的 Raku/Perl 精神中,有多种方法可以实现它(TMTOWTDI):
~$ raku -ne '.trans("ß" => "ẞ").uc.put;' file
~$ raku -e '.trans("ß" => "ẞ").uc.put for lines();' file
~$ raku -e 'put .trans("ß" => "ẞ").uc for lines();' file
~$ raku -e 'slurp.trans("ß" => "ẞ").uc.put;' file
~$ raku -e 'slurp.trans( "\x[00DF]" => "\x[1E9E]" ).uc.put;' file
~$ raku -e 'slurp.trans("LATIN SMALL LETTER SHARP S".uniparse => "LATIN CAPITAL LETTER SHARP S".uniparse).uc.put;' file

2. 折叠大小写:

Unicode联盟发布了一个规则,即折叠大小写对应关系应该是稳定的(根据Unicode Casefolding Stability Policy)。

至于fc折叠大小写的稳定性,我曾希望先将"ß" => "ẞ"进行转换,以提供一个“第30个大写字符”,作为小写ß的双重大小写折叠伙伴(成对出现)。下面的代码似乎很有前途,因为从一个小型混合大小写文本样本开始,您可以从大写转换为小写,仍然具有与小写匹配的输出文本:

~$ raku -ne 'for .words {print $_.uc.lc eq $_.lc }; "".put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse
~$ raku -ne 'for .words {print $_.trans("ß" => "ẞ").uc.lc eq $_.lc }; "".put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
TrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrue

然而,下面的fc折叠大小写代码表明,目前的操作是将大写的转换为小写的ss(而不是小写的ß)。基本上,.fc折叠大小写会将大写的SS转换为小写的ss,无论如何:
~$ raku -ne '.trans("ß" => "ẞ").fc.put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
mass strasse griess spiess gross grüssen aussen ausser draussen strauss beissen fleiss heissen
~$ raku -ne 'for .words {print $_.trans("ß" => "ẞ").uc.fc eq $_.fc }; "".put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
TrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrueTrue
~$ raku -ne 'for .words {print $_.trans("ß" => "ẞ").uc.lc eq $_.fc }; "".put;' TO_ẞ_OR_NOT_TO_ẞ_tclc.txt
FalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse

有什么变化吗?根据2017年StackOverflow的一篇文章,"只需等半个世纪。"

https://raku.org


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接