封裝漢字轉拼音邏輯,支援分隔符、首字母大寫、例外詞組覆蓋。
static Hashtable _phrase;
public static Hashtable Phrase
{
get
{
if (_phrase == null)
{
_phrase = new Hashtable();
_phrase.Add("重慶", "Chong Qing");
_phrase.Add("深圳", "Shen Zhen");
_phrase.Add("什麼", "Shen Me");
}
return _phrase;
}
set => _phrase = value;
}
轉換前優先替換例外詞組,避免逐字拼音錯誤(如「重慶」→ "Chong Qing" 而非 "Zhong Qing")。
public static string Convert(string chs, string separator = "", bool initialCap = false)
{
if (string.IsNullOrEmpty(chs)) return "";
if (string.IsNullOrEmpty(separator)) separator = "";
// 1. 例外詞組替換
foreach (DictionaryEntry de in Phrase)
chs = chs.Replace(de.Key.ToString(),
$" {de.Value.ToString().Replace(" ", separator)} ");
var bytes = new byte[2];
var result = new StringBuilder();
bool prevWasAscii = false;
foreach (char c in chs)
{
bytes = Encoding.Default.GetBytes(c.ToString());
if (bytes.Length == 1) // ASCII
{
result.Append(c);
prevWasAscii = true;
continue;
}
// 特殊處理問號
if (c == '?')
{
result.Append(prevWasAscii || result.Length == 0 ? "?" : separator + "?");
continue;
}
// GB2312 區位碼計算
short zone = bytes[0], pos = bytes[1];
int gbCode = zone * 256 + pos - 65536; // 負數編碼
// 二分查找 pv 找到最大 pv[i] <= gbCode
for (int i = pv.Length - 1; i >= 0; i--)
{
if (pv[i] <= gbCode)
{
string py = ps[i];
if (initialCap) py = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(py);
result.Append((result.Length == 0 || prevWasAscii) ? py : separator + py);
break;
}
}
prevWasAscii = false;
}
return result.ToString().Replace(" ", separator);
}
public static string Convert(string chs, string separator) => Convert(chs, separator, false);
public static string Convert(string chs, bool initialCap) => Convert(chs, "", initialCap);
public static string Convert(string chs) => Convert(chs, "");
CHS2PinYin.Convert("深圳歡迎你") // "Shen Zhen Huan Ying Ni"
CHS2PinYin.Convert("深圳歡迎你", " ") // "Shen Zhen Huan Ying Ni"
CHS2PinYin.Convert("深圳歡迎你", "-", true) // "Shen-Zhen-Huan-Ying-Ni"