首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 漢字轉拼音功能類(二):CHS2PinYin 完整實作與例外詞組支援

     編輯:關於C語言

核心類別 `CHS2PinYin`

封裝漢字轉拼音邏輯,支援分隔符、首字母大寫、例外詞組覆蓋。

核心資料表

  • `pv[]`:20,902 個漢字區位碼對應的負數編碼(GB2312 區位轉換基礎)。
  • `ps[]`:對應拼音字串陣列(無聲調),長度與 `pv` 一致。
  • `bd[]`:標點符號排除表(轉換時保留原字符)。

例外詞組表 `Phrase`


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")。

核心轉換邏輯 `Convert`


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"

已知限制

  • 依賴 `Encoding.Default`(系統 ANSI 頁面),跨地區執行可能不一致,建議明確指定 `Encoding.GetEncoding("GB2312")`。
  • 不支援多音字(單一拼音映射)、聲調標記、姓名/地名專有讀音(需擴展例外表)。
  • 效能:線性掃描 `pv` 陣列,可改用二分查找或 `Dictionary` 優化至 O(log n)/O(1)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved