成都心情

            BlogJava :: 首頁 ::  :: 聯(lián)系 :: 聚合  :: 管理 ::
            98 隨筆 :: 2 文章 :: 501 評論 :: 1 Trackbacks

          公告

          Creative Commons License
          本作品采用知識共享署名-相同方式共享 2.5 中國大陸許可協(xié)議進(jìn)行許可。 Locations of visitors to this page(15)

          隨筆分類(91)

          隨筆檔案(99)

          文章分類(2)

          友情鏈接

          積分與排名

          • 積分 - 635653
          • 排名 - 74

          最新評論

          閱讀排行榜

          評論排行榜

          開發(fā)中經(jīng)常遇到,字符串過長,無法完全顯示的問題

          這時候就需要截取我們所需要的長度,后面顯示省略號或其他字符。

          由于中文字符占兩個字節(jié),而英文字符占用一個字節(jié),所以,單純地判斷字符數(shù),效果往往不盡如人意

          下面的方法通過判斷字符的類型來進(jìn)行截取,效果還算可以:)


          如果大家有其他的解決方法歡迎貼出來,共同學(xué)習(xí):)
          **********************************************************************
          private String str;
          private int counterOfDoubleByte;
          private byte b[];
          /**
          * 設(shè)置需要被限制長度的字符串
          * @param str 需要被限制長度的字符串
          */
          public void setLimitLengthString(String str){
            this.str = str;
          }
          /**
          * @param len 需要顯示的長度(<font color="red">注意:長度是以byte為單位的,一個漢字是2個byte</font>)
          * @param symbol 用于表示省略的信息的字符,如“...”,“>>>”等。
          * @return 返回處理后的字符串
          */
          public String getLimitLengthString(int len, String symbol) throws UnsupportedEncodingException {
            counterOfDoubleByte = 0;
            b = str.getBytes("GBK");
            if(b.length <= len)
              return str;
            for(int i = 0; i < len; i++){
              if(b[i] < 0)
                counterOfDoubleByte++;
            }

            if(counterOfDoubleByte % 2 == 0)
              return new String(b, 0, len, "GBK") + symbol;
            else
              return new String(b, 0, len - 1, "GBK") + symbol;
          }


          本文轉(zhuǎn)貼自網(wǎng)友:focus2004 的文章
          posted on 2005-08-12 15:39 Rosen 閱讀(8690) 評論(15)  編輯  收藏 所屬分類: Java EE 服務(wù)器端

          評論

          # re: 精確截取字符串(轉(zhuǎn)載) 2005-08-19 08:27 ivan
          if(b<0) 編譯會出錯。  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2005-08-19 20:39 Rosen
          馬上修改一下代碼,去年轉(zhuǎn)貼的時候一直忘記修改了。
          是 if(b[i] < 0),謝謝 ivan 指正。  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2006-01-28 18:24 tdg
          大作拜讀,有一點(diǎn)愚見,特拋磚引玉:
          1。字符串除了可以基于byte[]操作外,還可以基于char[]操作。看老大你的意圖是想截取字符串的前幾個字符然后加上省略符號最后輸出而已,完全不必考慮用byte[]數(shù)組操作啊 。而且好像開發(fā)中更注重語義上的第幾個字符而不是你說的這種情況哦。
          2。以下是拙作,請斧正:
          /**
          * 字符串截取函數(shù)
          * @param str String 要處理的字符串
          * @param length int 需要顯示的長度
          * @param symbol String 用于表示省略的信息的字符,如“...”,“>>>”等
          * @return String 返回處理后的字符串
          * @throws UnsupportedEncodingException
          */
          public String getLimitLengthString(String str, int length, String symbol) throws
          UnsupportedEncodingException {
          assert str != null;
          assert length > 0;
          assert symbol != null;
          //如果字符串的位數(shù)小于等于要截取的位數(shù),附加上表示省略的信息的字符串后返回
          if (str.length() <= length) {
          return str + symbol;
          //從零開始,截取length個字符,附加上表示省略的信息的字符串后返回
          } else {
          str = new String(str.getBytes("GBK"));
          char[] charArray = str.toCharArray();
          char[] charArrayDesc = new char[length];
          System.arraycopy(charArray, 0, charArrayDesc, 0, length);
          return new String(charArrayDesc) + symbol;
          }
          }  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2006-01-28 20:03 Rosen
          呵呵 tdg 兄很認(rèn)真喔,談不上斧正。主要是這個問題,用 char 處理,如果是字母或者數(shù)字,實(shí)際上截取出來的會比漢字少占用一半的空間,所以截取出來后,還是不能對齊。而實(shí)際上 char 數(shù)組中,不管是字母、數(shù)字還是漢字,它們都只代表一個單元。但是 byte 則不同,字母、數(shù)字只占用一個字節(jié),而漢字占用兩個字節(jié)(都是GBK編碼)。  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2006-03-24 10:49 istarliu
          您好!
          你的文章讓我受益不少,有個問題想向您確認(rèn)一下:
          在代碼中
          b = str.getBytes("GBK");
          if(b.length <= len)
          return str;
          for(int i = 0; i < len; i++){
          if(b[i] < 0)
          counterOfDoubleByte++;
          }
          是不是如果只要是中文漢字,在b[i]對應(yīng)的值都是小于0的,
          也就是說,在漢字代表的兩個字節(jié)中,這兩個漢字分別轉(zhuǎn)化為整數(shù)值時,是不是一定小于0,但值范圍不能小于-127的。做過測試,不能肯定。:)

            回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2006-03-30 17:42 Rosen
          istarliu,這里要強(qiáng)調(diào)一下,GBK、GB2312 雙字節(jié)編碼字節(jié)才是負(fù)的。UTF-8 三字節(jié)編碼未去核實(shí)。  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2007-01-19 16:28 lyazure
          無意義的做法, 犯了常識錯誤, java內(nèi)部表示任何字符都是16位, 而且不涉及輸入輸出操作不需要字符解碼編碼操作.不知道文中的"單純地判斷字符數(shù)效果并不理想"的結(jié)論如何得出,恐怕只是臆斷.事實(shí)上只需根據(jù)字符數(shù)截取即可.
          public String getLimitLengthString(String srcString, int expectLength){
          if(srcString.length() <= expectLength) return srcString;
          return srcString.subString(0, expectLength);
          }  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2007-01-19 23:19 Rosen
          @lyazure
          我只想說一句,請驗(yàn)證后再回答,最好能打印在 html 頁面中,然后混合漢字和數(shù)字輸出,看看長短是否一致。  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2007-01-20 07:08 lyazure
          不知Rosen驗(yàn)證原文中代碼用的是怎樣的例子,能否可以提供一個我不能處理的字符串或者這樣的情境?
          從文中的涉及對字符解碼操作來看, 接收到的參數(shù)字符串并未正確解碼, 關(guān)鍵不在字符長度處理的問題.只需先對字符串進(jìn)行正確解碼.
          String desString = new String(srcString.getBytes("ISO-8859-1"), "GBK");
          之后所有字符操作都可以正常進(jìn)行,不會出現(xiàn)字符長度問題.
          另外,從文中的意義看來, 原文對字符的解碼應(yīng)當(dāng)用ISO-8859-1,而不是GBK,當(dāng)然,因?yàn)镚BK向下兼容ISO-8859-1,因此從結(jié)果來說并沒有問題.
          之前的評論有些詞語過激,希望Rosen不要往心里去. 但似乎Rosen的回答馬上有針鋒相對的味道,呵呵.希望是我多慮了.  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2007-01-20 14:07 Rosen
          @lyazure
          還不是很激動,只是感覺本文的意思沒有完全表達(dá)清楚,應(yīng)該再加點(diǎn)描述,比如這樣的例子:
          字符串“中文中文2222”,當(dāng)直接截取srcString.substring(0, 4)時,“中文中文”這四個字會正確打印出來,沒錯。不過如果我們把字符串改為“2222中文中文”,那么打印出來的應(yīng)該是“2222”。
          這個時候輸出到 html 是這樣的:
          中文中文
          2222

          可以看到,雖然我都是截取的同樣長度,但是頁面卻很不美觀,長短不一,一個現(xiàn)實(shí)中的例子,當(dāng)然也是我一直沒有糾正過來的錯誤,http://www.cdcin.com,你看首頁的“新聞信息”欄目,當(dāng)出現(xiàn)標(biāo)題有數(shù)字的情況時,就顯得很不統(tǒng)一,參差不齊。

          所以,這就是本文為什么要討論按照編碼規(guī)則來截取字符串的原因。當(dāng)然,這樣處理并不會徹底的解決不整齊,但是總會好些,比如哪天發(fā)布某條全是數(shù)字和字母的標(biāo)題,那這種參差不齊就太嚴(yán)重了。  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2007-01-20 18:38 lyazure
          看來我理解錯了,原來是為了獲得一致的顯示寬度.
            回復(fù)  更多評論
            

          # 我的做法 2007-04-24 15:16 國家機(jī)器
          /***
          * 字符串的單個字符是否是漢字
          * @param c
          * @return
          */
          public static int ascii(String c)
          {
          byte x[] = new byte[2];
          x = c.getBytes();

          if (null == x || x.length > 2 || x.length <=0)
          {
          return 0;
          }

          if( x.length == 1){ //英文字符
          return x[0];
          }

          if (x.length == 2)
          {
          int hightByte = 256 + x[0];
          int lowByte = 256 + x[1];
          int ascii = (256 * hightByte + lowByte) - 256 * 256;
          return ascii;
          }

          return 0;
          }

          /***
          * 顯示字符串的前N個字符
          * 此處著重處理了英文字符和中文字符在顯示上的一致性;
          * 2個英文字符和一個漢字占據(jù)的寬度一致;
          */
          public static String limitStr(String string, int size)
          {
          if (null != string)
          {
          string = goodStr(string);
          if (string.length() <= size)
          {
          return string;
          }
          else
          {
          StringBuffer buffer = new StringBuffer();
          double len = 0;
          for (int i = 0; i < string.length(); i++)
          {
          //是否漢字 ascii<0
          String str = string.substring(i,i+1);
          if (ascii(str) < 0 )
          {
          buffer.append(str);
          len ++ ;
          }
          else
          {
          buffer.append(str);
          len = len + 0.5;
          }

          if (len >= size) break;
          }
          return buffer.toString();
          }

          }
          return "";
          }  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2007-05-14 11:44 Rosen
          @國家機(jī)器
          呵呵,感謝貢獻(xiàn),你的做法更精確了。
            回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2016-08-18 17:22 JustPassoner
          @國家機(jī)器
          六六,認(rèn)識你是我等榮幸,酒瘋知己千杯燒...  回復(fù)  更多評論
            

          # re: 精確截取字符串(轉(zhuǎn)載) 2016-08-18 17:56 JustPassoner
          string=goodStr(string); 這個方法 是干什么用處的?  回復(fù)  更多評論
            

          主站蜘蛛池模板: 平顺县| 镇沅| 时尚| 丰都县| 隆德县| 南充市| 汤阴县| 慈利县| 仙居县| 鲁山县| 遵义县| 大庆市| 麻城市| 织金县| 麻栗坡县| 西贡区| 乌恰县| 军事| 调兵山市| 井研县| 奈曼旗| 浪卡子县| 内江市| 望城县| 启东市| 于田县| 绍兴县| 廊坊市| 韩城市| 张北县| 大渡口区| 清徐县| 江永县| 南郑县| 肇东市| 垫江县| 华宁县| 温宿县| 南木林县| 石柱| 玛纳斯县|