我正在设计一个API,其中API用户需要以Unicode格式返回阿拉伯文本,为此,我尝试了以下操作:
public static class StringExtensions
{
public static string ToUnicodeString(this string str)
{
StringBuilder sb = new StringBuilder();
foreach (var c in str)
{
sb.Append("\\u" + ((int)c).ToString("X4"));
}
return sb.ToString();
}
}
上述代码的问题是,无论其在单词中的位置如何,它都会返回字母的unicode。
示例:让我们假设我们有以下单词:
“سمير”,由以下内容组成:
'س'的写法类似于'سـ',因为它是单词中的第一个字母。
'م'的写法类似于'ـمـ',因为它位于单词的中间。
'ي'的写法类似于'ـيـ',因为它位于单词的中间。
'ر'的写法类似于'lastر',因为它是单词的最后一个字母。
上面的代码返回Unicode的{'س','م','ي','ر'},即:
\ u0633 \ u0645 \ u064A \ u0631
代替了
的{'سـ','ـمـ','ـيـ','ـر'}\ uFEB3 \ uFEE4 \ uFEF4 \ uFEAE
关于如何更新代码以获取正确的Unicode的任何想法?
有用的link
答案 0 :(得分:3)
字符串只是Unicode代码点的序列;它不知道阿拉伯语的规则。您可以准确地取出放入的数据;如果要输出不同的数据,请输入不同的数据!
尝试一下:
Console.WriteLine("\u0633\u0645\u064A\u0631");
Console.WriteLine("\u0633\u0645\u064A\u0631".ToUnicodeString());
Console.WriteLine("\uFEB3\uFEE4\uFEF4\uFEAE");
Console.WriteLine("\uFEB3\uFEE4\uFEF4\uFEAE".ToUnicodeString());
如预期的那样输出
سمير
\u0633\u0645\u064A\u0631
ﺳﻤﻴﺮ
\uFEB3\uFEE4\uFEF4\uFEAE
这两个Unicode代码点序列在浏览器中呈现相同的内容,但它们是不同的序列。如果要写出第二个序列,则不要通过第一个序列。
答案 1 :(得分:0)
基于Eric的回答,我知道如何解决问题,因此我在Github上创建了一个解决方案。
您将找到一个可在Windows上运行的简单工具,如果要在项目中使用代码,则只需复制粘贴UnicodesTable.cs
和Unshaper.cs
。
基本上,每个阿拉伯字母都需要一个Unicode表,然后可以使用以下扩展方法。
public static string GetUnShapedUnicode(this string original)
{
original = Regex.Unescape(original.Trim());
var words = original.Split(' ');
StringBuilder builder = new StringBuilder();
var unicodesTable = UnicodesTable.GetArabicGliphes();
foreach (var word in words)
{
string previous = null;
for (int i = 0; i < word.Length; i++)
{
string shapedUnicode = @"\u" + ((int)word[i]).ToString("X4");
if (!unicodesTable.ContainsKey(shapedUnicode))
{
builder.Append(shapedUnicode);
previous = null;
continue;
}
else
{
if (i == 0 || previous == null)
{
builder.Append(unicodesTable[shapedUnicode][1]);
}
else
{
if (i == word.Length - 1)
{
if (!string.IsNullOrEmpty(previous) && unicodesTable[previous][4] == "2")
{
builder.Append(unicodesTable[shapedUnicode][0]);
}
else
builder.Append(unicodesTable[shapedUnicode][3]);
}
else
{
bool previouChar = unicodesTable[previous][4] == "2";
if (previouChar)
builder.Append(unicodesTable[shapedUnicode][1]);
else
builder.Append(unicodesTable[shapedUnicode][2]);
}
}
}
previous = shapedUnicode;
}
if (words.ToList().IndexOf(word) != words.Length - 1)
builder.Append(@"\u" + ((int)' ').ToString("X4"));
}
return builder.ToString();
}