public static String ConvertToPinyin(String str)
{
if (String.IsNullOrEmpty(str)) return String.Empty;
var sb = new StringBuilder(str.Length * 10);
var chs = str.ToCharArray();
for (var j = 0; j < chs.Length; j++)
{
sb.Append(Get(chs[j]));
}
return sb.ToString();
}
public static String Get(Char ch)
{
// 拉丁字符
if (ch <= '\x00FF') return ch.ToString();
// 标点符号、分隔符
if (Char.IsPunctuation(ch) || Char.IsSeparator(ch)) return ch.ToString();
// 非中文字符
if (ch < '\x4E00' || ch > '\x9FA5') return ch.ToString();
var arr = Encoding.GetEncoding("gb2312").GetBytes(ch.ToString());
//Encoding.Default默认在中文环境里虽是GB2312,但在多变的环境可能是其它
//var arr = Encoding.Default.GetBytes(ch.ToString());
var chr = (Int16)arr[0] * 256 + (Int16)arr[1] - 65536;
//***// 单字符--英文或半角字符
if (chr > 0 && chr < 160) return ch.ToString();
#region 中文字符处理
// 判断是否超过GB2312-80标准中的汉字范围
if (chr > lastChCode || chr < firstChCode)
{
return ch.ToString(); ;
}
// 如果是在一级汉字中
else if (chr <= lastOfOneLevelChCode)
{
// 将一级汉字分为12块,每块33个汉字.
for (int aPos = 11; aPos >= 0; aPos--)
{
int aboutPos = aPos * 33;
// 从最后的块开始扫描,如果机内码大于块的第一个机内码,说明在此块中
if (chr >= pyValue[aboutPos])
{
// Console.WriteLine("存在于第 " + aPos.ToString() + " 块,此块的第一个机内码是: " + pyValue[aPos * 33].ToString());
// 遍历块中的每个音节机内码,从最后的音节机内码开始扫描,
// 如果音节内码小于机内码,则取此音节
for (int i = aboutPos + 32; i >= aboutPos; i--)
{
if (pyValue[i] <= chr)
{
// Console.WriteLine("找到第一个小于要查找机内码的机内码: " + pyValue[i].ToString());
return pyName[i];
}
}
break;
}
}
}
// 如果是在二级汉字中
else
{
int pos = Array.IndexOf(otherChinese, ch.ToString());
if (pos != decimal.MinusOne)
{
return otherPinYin[pos];
}
}
#endregion 中文字符处理
return String.Empty;
}