为什么有些变音符号不能被去除?

4
我使用这个答案中的方法,将单词中的特殊字符删除并将其转换为简单形式。对于许多基本重音符号,这个方法处理得很好。
Malmö becomes "Malmo"
München becomes "Munchen"
Åge becomes "Age"

然而,这在一些其他字符上并不起作用,例如:
Strømsgodset remains "Strømsgodset"
Kulħadd remains "Kulħadd"

这些字符为什么不像其他字符一样被转换?是否有任何原因?

还有没有办法类似地转换“组合”字符,例如:

æ -> ae
ẞ -> ss

因为Unicode联盟的语言学家和官僚们做出了这样的决定。 - xanatos
根据你的第二个问题,如何将它们映射到一对其他字符,请使用 Dictionary<char, string>。然后就很容易了:foreach(var kv in dict) text=text.Replace(kv.Key.ToString(),kv.Value) - Tim Schmelter
2
如果你知道世界上每种语言中的所有特殊字符,那么这将起作用。 - Gigi
@Gigi 没有特殊字符。你说的就像在说寿司是特别的食物一样。 - xanatos
你的最终目标是什么?为什么需要将字母转换为所谓的简单形式?顺便说一下,Kullħadd多了一个“L”。 - Dialecticus
匹配搜索结果时不考虑重音符号。Kullħadd 是一份报纸,Kulħadd 的意思是“每个人”(我是马耳他人 :))。 - Gigi
1个回答

3
因为Unicode联盟编写的规范化表中没有您想要的分解,而Microsoft使用了该表(或更可能是该表的文本版本,或者可能是该表的旧版本,但这些都是细节问题)。
我不知道原因,因为我不是语言学家,但我希望Unicode联盟有足够优秀的语言学家做出正确的选择。
请注意,排序表与规范化表是分开的,所以您可以拥有:
int res = string.Compare("æ", "ae", CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace);

0... 所以 æ == aeħ == h

您甚至可以使用排序规则进行 IndexOf

int ix = CultureInfo.CurrentCulture.CompareInfo.IndexOf(
    "Ad aeternitatem", 
    "æter", 
    CompareOptions.IgnoreNonSpace); // 3

忽略大小写:
int ix = CultureInfo.CurrentCulture.CompareInfo.IndexOf(
    "Ad Aeternitatem", 
    "æter", 
    CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase); // 3

对于这些“双字符”是有意义的,但其他字符(例如ħ)也是如此吗? - Gigi
@gigi 它在图形上与 h 相似,并不意味着它就是 h。你想让 $ 符号被分解成 S| 吗? :-) - xanatos
开个玩笑,但是利用图形(而非语义)相似性的实际原因是很有用的,例如搜索。 - Gigi
@gigi 对于搜索,可以使用 CompareInfo.IndexOf。如果你想要的话,我可以发一个例子给你。它使用排序规则而不是规范化。 - xanatos
请务必这样做 :) - Gigi

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