[C#] 字串 Unicode 字碼辨識與繁簡字碼轉換心得筆記

字串 Unicode 字碼辨識與繁簡字碼轉換心得筆記

話說我發現自己的文章竟然有簡體版後,那就想試試C#下怎麼判別字碼跟做繁簡轉換的操作

OK!Here we GO~~


首先第一步先判別是否為合法合規的字串,就是非空(null)或非空白字串

public static bool IsStringInvalid(object obj)
{
    if (obj == null)                   return true;
    if (obj.ToString().Trim() == null) return true;
    if (obj.ToString() == "")          return true;

    return false;
}

這邊只是簡易的判斷,像有些特殊情況空寬空格(ZWSP, Zero-Width Space)也可以在此加入判斷

可以參照這兩篇文章來更了解 ZWSP


接下來第二步讓我們判斷字串是否屬於漢字碼

這邊用來判斷的 Unicode 字碼區段是 U+4E00 ~ U+9FFF, 

此區段真正名稱是「中日韓統一表意文字列表」,但大事不拘小節就讓我們稱這漢文字碼吧 XD

各位看倌們上碼了~XD

public static bool IsHanCode(string str, int index)
{
    int code = 0;
    int chFrom = Convert.ToInt32("4e00", 16);
    int chEnd  = Convert.ToInt32("9fff", 16);

    if (str != "")
    {
        // 取得字串中指定索引處的字元 Unicode 編碼
        code = Char.ConvertToUtf32(str, index);

        if (code >= chFrom && code <= chEnd)
        {
            return true;
        }

        return false;
    }

    return false;
}
public static bool IsContainHanString(string str)
{
    for (int i = 0; i < str.Length; i++)
    {
        if (IsHanCode(str, i))
        {
            return true;
        }
    }

    return false;
}

接下來這節,讓我們判斷使否為漢字碼內繁簡體字碼(Big5/GB/GBK)

先來繁體的 Big5 碼

public static bool IsBig5Code(string str)
{
    byte[] bytes = Encoding.GetEncoding("Big5").GetBytes(str.ToString());

    // 如果字串長度只有1Byte,則是 ASCII
    if (bytes.Length <= 1)
    {
        return false;
    }
    else
    {
        byte byte1 = bytes[0];
        byte byte2 = bytes[1];

        if ((byte1 >= 129 && byte1 <= 254) && 
           ((byte2 >=  64 && byte2 <= 126) || (byte2 >= 161 && byte2 <=254)))
        {
            return true;
        }

        return false;
    }
}
public static bool IsContainBig5String(string str)
{
    char[] words = str.ToCharArray();

    foreach (char word in words)
    {
        if (IsBig5Code(word.ToString()))
        {
            return true;
        }
        else
        {
            continue;
        }
    }

    return false;
}

再來簡體 GB2312 碼

public static bool IsGBCode(string str)
{
    byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(str.ToString());

    // 如果字串長度只有1Byte,則是 ASCII
    if (bytes.Length <= 1)
    {
        return false;
    }
    else
    {
        byte byte1 = bytes[0];
        byte byte2 = bytes[1];

        if (byte1 >= 176 && byte1 <= 247 && 
            byte2 >= 160 && byte2 <= 254)
        {
            return true;
        }

        return false;
    }
}
public static bool IsContainGBString(string str)
{
    char[] words = str.ToCharArray();

    foreach (char word in words)
    {
        if (IsGBCode(word.ToString()))
        {
            return true;
        }
        else
        {
            continue;
        }
    }

    return false;
}

再一發簡體 GBK 碼

public static bool IsGBKCode(string str)
{
    byte[] bytes = Encoding.GetEncoding("GBK").GetBytes(str.ToString());

    // 如果字串長度只有1Byte,則是 ASCII
    if (bytes.Length <= 1)
    {
        return false;
    }
    else
    {
        byte byte1 = bytes[0];
        byte byte2 = bytes[1];

        if (byte1 >= 129 && byte1 <= 254 && 
            byte2 >=  64 && byte2 <= 254)
        {
            return true;
        }

        return false;
    }
}
public static bool IsContainGBKString(string str)
{
    char[] words = str.ToCharArray();

    foreach (char word in words)
    {
        if (IsGBKCode(word.ToString()))
        {
            return true;
        }
        else
        {
            continue;
        }
    }

    return false;
}

觀察上一節的程式碼會發現核心是用以下這個功能函式

Encoding.GetEncoding("CharacterEncoding")

那就來實作一下繁簡字碼的轉換,這加入大部分應用程式都支援的 UTF-8,那就上碼吧~ XD

public static string Big5toUTF8(string str)
{
    Encoding Big5 = Encoding.GetEncoding("Big5");
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");

    byte[] tmp = Big5.GetBytes(str);
    tmp = Encoding.Convert(Big5, UTF8, tmp);

    return UTF8.GetString(tmp);
}
public static string UTF8toBig5(string str)
{
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");
    Encoding Big5 = Encoding.GetEncoding("Big5");

    byte[] tmp = UTF8.GetBytes(str);
    tmp = Encoding.Convert(UTF8, Big5, tmp);

    return Big5.GetString(tmp);
}
public static string GBtoUTF8(string str)
{
    Encoding GB   = Encoding.GetEncoding("GB2312");
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");

    byte[] tmp = GB.GetBytes(str);
    tmp = Encoding.Convert(GB, UTF8, tmp);

    return UTF8.GetString(tmp);
}
public static string UTF8toGB(string str)
{
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");
    Encoding GB   = Encoding.GetEncoding("GB2312");

    byte[] tmp = UTF8.GetBytes(str);
    tmp = Encoding.Convert(UTF8, GB, tmp);

    return GB.GetString(tmp);
}
public static string GBKtoUTF8(string str)
{
    Encoding GBK  = Encoding.GetEncoding("GBK");
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");

    byte[] tmp = GBK.GetBytes(str);
    tmp = Encoding.Convert(GBK, UTF8, tmp);

    return UTF8.GetString(tmp);
}
public static string UTF8toGBK(string str)
{
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");
    Encoding GBK  = Encoding.GetEncoding("GBK");

    byte[] tmp = UTF8.GetBytes(str);
    tmp = Encoding.Convert(UTF8, GBK, tmp);

    return GBK.GetString(tmp);
}

看了上節轉換字碼的程式後,細心的看倌應該發現如果就是要將字串轉到某個字碼下應該可行

的確是這樣,不然考量原始字碼情況下那排列組合真是太多了!

public static string ToUTF8(string str)
{
    Encoding UTF8 = Encoding.GetEncoding("UTF-8");

    byte[] tmp = Encoding.Default.GetBytes(str);
    tmp = Encoding.Convert(Encoding.Default, UTF8, tmp);

    return UTF8.GetString(tmp);
}
public static string ToBig5(string str)
{
    Encoding Big5 = Encoding.GetEncoding("Big5");

    byte[] tmp = Encoding.Default.GetBytes(str);
    tmp = Encoding.Convert(Encoding.Default, Big5, tmp);

    return Big5.GetString(tmp);
}
public static string ToGB(string str)
{
    Encoding GB = Encoding.GetEncoding("GB2312");

    byte[] tmp = Encoding.Default.GetBytes(str);
    tmp = Encoding.Convert(Encoding.Default, GB, tmp);

    return GB.GetString(tmp);
}
public static string ToGBK(string str)
{
    Encoding GBK = Encoding.GetEncoding("GB2312");

    byte[] tmp = Encoding.Default.GetBytes(str);
    tmp = Encoding.Convert(Encoding.Default, GBK, tmp);

    return GBK.GetString(tmp);
}

這邊都只是簡要列出轉換的部分,實作上還是要先加上前三節提到的字串字碼判斷

這部分就是個人的經驗談,主要是要避免有特殊情況沒考慮到~

完結灑花 XD