none
[C#] 有關字串切位 RRS feed

  • 問題

  • 各位先進大大們好~

    公司的 ERP 系統已經是 20 年的老舊系統了,
    使用的是 UNIFY 資料庫,中文字是 2byte,英文字是 1byte,
    有一張table每個欄位的長度都是 4,假設是這樣:

    產品名   說明1     說明2     說明3
    A          紅色      15kg       紅12
    B          粉紅      5kg         粉紅
    C          藍色      45kg       藍3


    後來公司導入 BI 系統,當時的前輩把  說明1. 說明2. 說明3 這三個欄位,
    在 BI 的 table 中合併為 product_spec 這個欄位,其中長度不足 4 均會補空白,也就是這樣:
    product_name    product_spec
    A                       紅色15kg紅12
    B                       粉紅5kg 粉紅       (5kg後面有一個空白字元)
    C                       藍色45kg藍3       (藍3後面有一個空白字元)

    當我從資料庫將 product_spec 的值撈出來之後,
    我要怎麼切位才能只擷取說明 3 的內容呢?謝謝。
    2009年4月27日 上午 09:00

解答

  • 劉大爺:
        看起來你的前輩是用固定長度的方法去合併那個字串,也就是長度一定是4Bytes+4Bytes+4Bytes,問題在於,因為有中文,所以會出現Hunter講的問題,中文也是1個Char,英文也是1個Char,因此直接用String.Substring 方法是一定不通的.
        1.有一個方法是應急用的,假設'g'的位置是一定會出現'g'字元,並且其它地方也不會出現,你可以用[String.Split 方法]來做
           以下為C#2005的例子
            private void button1_Click(object sender, EventArgs e)
            {
                string mystring;
                mystring = textBox1.Text;
                mystring = mystring.Split('g')[1];
                MessageBox.Show(mystring);
            }

         2.如果要依照你前輩原來的規則來做,有另一個方法是轉為Bytes再轉回String,這會用到[Encoding類別]
           以下為C#2005的例子
           private void button2_Click(object sender, EventArgs e)
            {
                System.Text.Encoding myEncoding = System.Text.Encoding.GetEncoding(950);
                Byte[] myBytes;
                string mystring;
                mystring = textBox1.Text;
                myBytes = myEncoding.GetBytes(mystring);
                Byte[] myOutputBytes = new Byte [4];
                           int i;
                int j;
                string[] myOutputstring= new string [3];
                for (i=0;i<=2;i++)
                {
                    for (j=0;j<=3;j++)
                    {
                        myOutputBytes[j]= myBytes[i*4+j];
                    }
                    myOutputstring[i]= myEncoding.GetString(myOutputBytes);
                }
                label1.Text = myOutputstring[0];
                label2.Text = myOutputstring[1];
                label3.Text = myOutputstring[2];
                }
       
    2009年4月27日 下午 12:44
    版主

所有回覆

  • Trim()可以移除空白字元
    2009年4月27日 上午 09:38
  • Descript3.PadRight(4,"");
    2009年4月27日 上午 09:46
  • 我先假設「說明2」這欄位一定都會有"kg"這字串,那麼最適合的方法應該是用 RegExp(命名空間:System.Text.RegularExpressions)
    作法大概如下:
    string[] texts = { "紅色15kg紅12", "粉紅5kg 粉紅", "藍色45kg藍3 " };
    string pat = @"kg(.*$)";
    Regex r = new Regex(pat, RegexOptions.IgnoreCase);
    foreach (string input in texts)
    {
        Match m = r.Match(input);
        Console.WriteLine(m.Groups[1].Value);
    }
    

    詳細用法可以參考http://msdn.microsoft.com/zh-tw/library/system.text.regularexpressions.regex.match.aspx,我是以"kg"只會出
    現一次,並且要保留「說明3」的空白字元,這些條件請視情況自行調整。

    補充一下,.NET 預設是以 Unicode UTF-16 來表示字元,所以不管中英文長度都是1...
    2009年4月27日 上午 10:10
  • 劉大爺:
        看起來你的前輩是用固定長度的方法去合併那個字串,也就是長度一定是4Bytes+4Bytes+4Bytes,問題在於,因為有中文,所以會出現Hunter講的問題,中文也是1個Char,英文也是1個Char,因此直接用String.Substring 方法是一定不通的.
        1.有一個方法是應急用的,假設'g'的位置是一定會出現'g'字元,並且其它地方也不會出現,你可以用[String.Split 方法]來做
           以下為C#2005的例子
            private void button1_Click(object sender, EventArgs e)
            {
                string mystring;
                mystring = textBox1.Text;
                mystring = mystring.Split('g')[1];
                MessageBox.Show(mystring);
            }

         2.如果要依照你前輩原來的規則來做,有另一個方法是轉為Bytes再轉回String,這會用到[Encoding類別]
           以下為C#2005的例子
           private void button2_Click(object sender, EventArgs e)
            {
                System.Text.Encoding myEncoding = System.Text.Encoding.GetEncoding(950);
                Byte[] myBytes;
                string mystring;
                mystring = textBox1.Text;
                myBytes = myEncoding.GetBytes(mystring);
                Byte[] myOutputBytes = new Byte [4];
                           int i;
                int j;
                string[] myOutputstring= new string [3];
                for (i=0;i<=2;i++)
                {
                    for (j=0;j<=3;j++)
                    {
                        myOutputBytes[j]= myBytes[i*4+j];
                    }
                    myOutputstring[i]= myEncoding.GetString(myOutputBytes);
                }
                label1.Text = myOutputstring[0];
                label2.Text = myOutputstring[1];
                label3.Text = myOutputstring[2];
                }
       
    2009年4月27日 下午 12:44
    版主
  • Dear Bill Chung,

    謝謝您的回覆,採用您的第二種方式,
    總算是解決了我目前面臨的困境,也讓我學習到了 Encoding 類別的用法。
    謝謝您!^^
    2009年4月28日 上午 01:03