用等效的简化字母数字字符转换非ascii多文化字符

本文关键字:ascii 文化 字符 转换 数字字符 简化字 | 更新日期: 2023-09-27 18:29:05

在使用unicode字符搜索文件名时遇到问题。这些文件可能具有正确或更改的名称(替换为等效的ascii字符)。我想制作一些代码来查找使用相同单词的文件,无论是否更改,在同一字符串中可能存在不连贯的文化混合。为了简单起见,我应该只管理欧洲语言中的字符串。

等效示例:

Ɛpsilon <=> epsilon
København <=> Kobenhavn
Ångström <=> Angstrom
El Niño <=> El Nino
Tiếng Việt <=> Tieng Viet
Čeština <=> Cestina
encyklopædi <=> encyklopaedi
Expediția <=> Expeditia
øðrum <=> odrum
œuf <=> oeuf
μ ('u03bc) <=> µ ('u00b5)
Straße <=> Strasse

我已经找到了一些类似问题的答案,但它们是基于更简单的字符串(去掉重音就足够了,使用Unicode规范化和去掉变音符号),或者基于"自己动手"。

如何比较Unicode字符;长得很像";?

如何将Unicode字符转换为ASCII等效

替换C#(ascii)中的字符

不幸的是,Unicode规范化(自动方式)至少在以下字符上不起作用:

Ɛ ø ð => missing equivalence
æ œ ß => missing expansion

有没有一个函数/库可以在C#中实现这一点,除了自己手动转换每个"众所周知"的字符?

用等效的简化字母数字字符转换非ascii多文化字符

我不认为有一种简单的方法可以做到这一点。可能没有通用的规范化(即使您将其限制在欧洲语言组中)

所有解决方案都有手动操作:

  1. RegEx-这应该是可能的,但这个解决方案(一个可以完成任务的RegEx表达式)真的太疯狂了
  2. Total Commander有(或者至少有)一个用于音译的插件。但是该插件存在错误/不稳定,您需要手动编写音译表
  3. "手动音译"

我对文件名也有类似的问题。但在我的情况下,文件名包含日语字符。这个翻译/音译有点难。

为了简化您的解决方案,您可以在Windows中使用代码页转换。如果转换为ASCII(7位)就可以了,那就太好了,但不是。这只会产生"?"字符。

这个例子应该处理一些字符。

  Encoding encoding;
  string data = "Čeština, øðrum";
  encoding = Encoding.GetEncoding(1250);
  data = encoding.GetString(encoding.GetBytes(data)); // "Čeština, o?rum"
  encoding = Encoding.GetEncoding(1252);
  data = encoding.GetString(encoding.GetBytes(data)); // "Ceština, o?rum"
  encoding = Encoding.ASCII;
  data = encoding.GetString(encoding.GetBytes(data));
  Console.WriteLine(data); // "Ce?tina, o?rum"

它并不完美,但至少在不需要替换字典的情况下清除了一些不需要的字符。您可以尝试添加其他代码页(希腊代码页可能会解决"μ"问题,但可能会删除所有其他字符)

在这些开始转换之后,您可以在转换后的文本中搜索"?"字符,看看是否有"?"原始/源中的字符。如果没有,现在您可以使用替换字典来替换给定的字符。

在我的项目中,我使用替换字典(由用户在运行时手动更新未知单词)。当所有的音译都是单个字符时,您不需要使用一些特殊的方法,但当出现类似"ßs"-->"ss"(而不是"''223e'+'s'="ss"+'s'="sss")的情况时,您将需要一个排序的替换列表,这些替换需要在字符替换之前进行处理。列表应该按字符串长度(先长一点)排序,而不是按字母表排序。

备注

  1. 在你的情况下,可能不存在歧义转录的问题(明日 ="ashita"或"asu",或者根据周围的字符可能是一个不同的词),但你应该考虑是否真的是这样。

  2. 在我的项目中,我发现有些程序存储的文件编码错误。下载程序获取UTF-8格式的正确文件名-字节序列被解释为Encoding.Default(或"Encoding.DOS"[符号名称],或压缩文件的其他代码页)。因此,最好测试文件名是否存在这种类型的错误。

查看如何测试无效的文件名编码:https://stackoverflow.com/a/19068371/2826535

  1. 只是为了完成答案:

基于Unicode规范化的"删除重音符号"方法:https://stackoverflow.com/a/3288164/2826535