功能特色
- 中文字串轉拼音(支援基本多音字預設讀音)
- 自訂拼音間分隔符(如空格、連字號、逗號)
- 選擇性首字母大寫
- 可擴充詞組讀音表(如「重慶」→ "Chong Qing")
- 可排除標點符號不轉換
輸出範例
輸入: "引發 system.Web.UI.Control.Init 事件以對頁進行初始化"
輸出: "Yin-Fa system.Web.UI.Control.Init Shi-Jian-Yi-Dui-Ye-Jin-Xing-Chu-Shi-Hua"
輸入: "Hello!重慶和深圳的特色各是什麼呢?"
輸出: "Hello!Chong Qing He Shen Zhen De Te Se Ge Shi ShenMe Ne ?"
核心原理
- 區碼對照表:
pv[] 存儲 GB2312 區位碼對應的有序負數編碼,ps[] 存對應拼音。
- 編碼計算:取字元 GB2312 位元組 →
chrasc = byte1 * 256 + byte2 - 65536 → 二分搜尋 pv 找最大 ≤ chrasc 的索引 → 取 ps[index]。
- 例外詞組優先替換:先用
Hashtable Phrase 替換已知詞組(如「重慶」),再逐字處理剩餘文字。
- 非中字元直通:ASCII、標點等直接保留或依設定加分隔符。
關鍵程式碼片段
public sealed class CHS2PinYin
{
private static readonly int[] pv = { -20319, -20317, ... }; // 區碼邊界
private static readonly string[] ps = { "a", "ai", "an", ... }; // 拼音表
private static readonly string[] bd = { ",", "。", "「", "」", ... }; // 排除字元
private 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; }
}
public static string Convert(string chs, string separator, bool initialCap)
{
if (string.IsNullOrEmpty(chs)) return "";
if (separator == null) separator = "";
// 1. 例外詞組替換
foreach (DictionaryEntry de in Phrase)
chs = chs.Replace(de.Key.ToString(),
" " + de.Value.ToString().Replace(" ", separator) + " ");
// 2. 逐字轉換
byte[] bytes = new byte[2];
StringBuilder sb = new StringBuilder();
bool lastWasAscii = false;
foreach (char c in chs)
{
bytes = Encoding.Default.GetBytes(c.ToString());
if (bytes.Length == 1) // ASCII / 標點
{
sb.Append(c);
lastWasAscii = true;
continue;
}
int chrasc = bytes[0] * 256 + bytes[1] - 65536;
string py = null;
for (int i = pv.Length - 1; i >= 0; i--)
if (pv[i] <= chrasc) { py = ps[i]; break; }
if (initialCap && py != null)
py = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(py);
if (sb.Length == 0 || lastWasAscii) sb.Append(py);
else sb.Append(separator).Append(py);
lastWasAscii = false;
}
return sb.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, "");
}
使用方式
// 預設:無分隔符、小寫
string py1 = CHS2PinYin.Convert("漢字轉拼音"); // "hanzizhuanpinyin"
// 自訂分隔符、首字大寫
string py2 = CHS2PinYin.Convert("漢字轉拼音", "-", true); // "Han-Zi-Zhuan-Pin-Yin"
// 擴充詞組表
CHS2PinYin.Phrase.Add("長沙", "Chang Sha");
string py3 = CHS2PinYin.Convert("長沙真好", " "); // "Chang Sha Zhen Hao"
限制與擴充方向
- 基於 GB2312,不支援生僻字/繁體字(需擴充對照表或改用 Unicode 方案)。
- 多音字僅能靜態預設,無法上下文動態斷詞(需結合 NLP 分詞器)。
- 效能:長字串建議用
StringBuilder(已採用)並快取編碼查詢結果。