将字符串转换为序数的大写或小写形式

16

是否有可能将字符串转换为序数的大写或小写格式,类似于不变量。

string upperInvariant = "ß".ToUpperInvariant();
string lowerInvariant = "ß".ToLowerInvariant();
bool invariant = upperInvariant == lowerInvariant; // true

string upperOrdinal = "ß".ToUpperOrdinal(); // SS
string lowerOrdinal = "ß".ToLowerOrdinal(); // ss
bool ordinal = upperOrdinal == lowerOrdinal; // false

如何实现ToUpperOrdinal和ToLowerOrdinal?

编辑: 如何获得序数字符串表示?同样地,如何获得不变字符串表示?也许在上述情况中可能是有歧义的,至少对于序数表示来说是这样。

编辑2:

string.Equals("ß", "ss", StringComparison.InvariantCultureIgnoreCase); // true
但是。
"ß".ToLowerInvariant() == "ss"; // false

2
@diiN__________ 我认为扩展方法的概念并不是 OP 需要帮助的地方。他们只是不知道这样一个方法的代码应该是什么。 - Broots Waymb
9
没有序数字符串表示,因为序数比较意味着“比较每个字节”。 - Tim Schmelter
1
@TimSchmelter,所以为什么存在StringComparison.OrdinalIgnoreCase,哪些字节是区分大小写的? - Wouter
3
因为它首先将它们转换为大写字母。根据文档,OrdinalIgnoreCase属性返回的TheStringComparer将字符串中要比较的字符视为使用不变文化的约定转换为大写字母。 - Charles Mager
@TimSchmelter 这些参考源代码都是外部的...您还看到我的第二个编辑了吗?在序数比较中将它们大写的规则是什么?(也许是ASCII的前127字节...但是对于Unicode呢?) - Wouter
显示剩余6条评论
2个回答

2
我不相信在 .NET Framework 或 .NET Core 中存在这种功能。最接近的东西是 string.Normalize(),但它缺少您需要成功实现此操作的大小写折叠选项。
这个功能在ICU项目中存在(可用于C/Java)。你需要的功能是C语言中的unorm2.h文件或Java中的Normalizer2类。在Java示例用法相关测试中可以找到相关信息。
据我所知,有两个实现了Normalizer2并移植到C#的版本。
  • icu-dotnet(用于 ICU4C 的 C# 封装库)
  • ICU4N(ICU4J 的完全托管的移植版本)

完整披露:我是 ICU4N 的维护者。


感谢这个添加。从我在MSDN上所读的来看,Normalize不会改变大小写,只是规范化许多等效的二进制表示。我还发现Unicode 00df和1e9e是相关的。但是,一些方式下1e9e不是00df的大写。请参阅:http://www.fileformat.info/info/unicode/char/00df/index.htm 和http://www.fileformat.info/info/unicode/char/1e9e/index.htm。 - Wouter
是的,这就是为什么我在我的回答中提到它还不够完善。要使其像这样工作,需要调用ICU unorm2.h。最好模仿Java Normalizer2类的API,并将其放入icu.net项目中,以便每个人都可以使用。 - NightOwl888

1

来自msdn

OrdinalIgnoreCase属性返回的TheStringComparer将要比较字符串中的字符视为使用不变区域性的约定转换为大写字母,然后执行独立于语言的简单字节比较。

但我猜这样做不会达到你想要的效果,因为仅仅使用"ß".ToUpperInvariant()并不能给你一个与"ss"在序数上等效的字符串。在String.Equals方法中必须有一些处理为什么“ss”等于'ß'特殊情况的魔法。

如果你只关心德文文本,那么这个回答或许可以帮助你


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