[分享] 好用的字串切除器 (原創大推薦)

  • 9629
  • 0
  • 2010-08-11

摘要:[分享] 好用的字串切除器 (原創大推薦)

首先新增一個類別 HandledString 如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace StringHandling
{
    /// <summary>
    /// 經StringHandler類別的CutDown方法處理過後的字串物件
    /// </summary>
    public class HandledString
    {
        /// <summary>
        /// 自訂參數的建構子
         /// </summary>
        /// <param name="isCut">是否被裁切過</param>
        /// <param name="resultString">處理過後的字串</param>
        internal HandledString(bool isCut, string resultString)
        {
            this.IsCut = isCut;
            this.ResultString = resultString;
        }

        /// <summary>
        /// 是否被裁切過
        /// </summary>
        public bool IsCut
        {
            set;
            get;
        }

        /// <summary>
        /// 處理過後的字串
        /// </summary>
        public string ResultString
        {
            set;
            get;
        }
    }
}

然後再新增一個類別如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace StringHandling
{
    /// <summary>
    /// 字串處理類別
    /// </summary>
    public static class StringHandler
    {
        /// <summary>
        /// 字串切除器(依照Byte數來切字串,不是依照字元數)
        /// </summary>
        /// <param name="strData">欲切除的字串</param>
        /// <param name="strLength">最大Byte數</param>
        /// <returns>處理過後的字串物件</returns>
        public static HandledString CutDown(this string strData, int strLength)
        {
            char[] strArrData = strData.ToCharArray();
            int byteLength = 0;
            string strResult = "";
            for (int i = 0; i < strData.Length; i++)
            {
                byte[] tempArrByte = Encoding.Default.GetBytes(strData[i].ToString());

                //如果 byte 陣列的長度為 1 且 第一個元素 ToString 為 "63" (問號),
                //表示編碼之後沒有對應的 byte, 因此會編成 ? 號
                //這樣的狀況下一定是佔了兩個 byte
                if (tempArrByte.Length == 1 && tempArrByte[0].ToString() == "63")
                {
                    byteLength += 2;
                }
                //有得正確編碼的字, 看 byte 陣列多長就佔幾個 byte~~~
                else
                {
                    byteLength += tempArrByte.Length;
                }
                strResult += strData[i];
                if (byteLength >= strLength)
                {
                    return new HandledString(true, strResult);
                }
            }
            return new HandledString(false, strData);
        }

        /// <summary>
        /// 字串切除器(依照字元數來切字串)
        /// </summary>
        /// <param name="strData">欲切除的字串</param>
        /// <param name="strLength">最大字元數</param>
        /// <returns>處理過後的字串物件</returns>
        public static HandledString CutDownByChar(this string strData, int strLength)
        {
            if (strLength >= strData.Length)
            {
                return new HandledString(false, strData);
            }
            else
            {
                return new HandledString(true, strData.Substring(0, strLength));
            }
        }
    }
}

使用方法是這樣: 

//記得先 using StringHandling
int max = 20; //字數最多20個字元
HandledString hString = "欲切除的字串".CutDown(max);
bool isCut = hString.IsCut; //是否被切過了
string resultString = hString.ResultString; //處理過的字串

為什麼不直接用 String.Length 就好了呢???

因為在需要切字串的地方對英數字或是中文字(或其他兩位元組的字)很敏感,
如果用 String.Length,那整串英數字跟整串中文字的長度一定是「差很大」,
這樣就完全沒辦法達到「因為字數過多要控板面所以要切字串」的原意了。
 

經由簡單的類別處理後,雖然還是會受到網頁採用的字型所影響,無法很精確的把字串的寬度固定住,
但至少比光採用 String.Length 來得好太多了~~~~~~。

 

2010/08/09 更新經由同事 Cross 的提點,將這邊使用的類別改成 String 的擴充功能,這樣就不用去記類別名稱了~~~ 讚~!
而擴充方法的使用可以參考 蹂躪 大大的 [C#][VB.NET]擴充方法 (Extension Method)
2010/08/10 更新結合蹂躪大大跟Allen大大的做法,弄了一個專案在這邊,有需要研究的同學請下~~~
WindowsFormsApplication3.rar