成都心情

  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理 ::
  98 随笔 :: 2 文章 :: 501 评论 :: 1 Trackbacks
开发中经常遇到,字符串过长,无法完全显示的问题

这时候就需要截取我们所需要的长度,后面显示省略号或其他字符。

由于中文字符占两个字节,而英文字符占用一个字节,所以,单纯地判断字符数,效果往往不尽如人意

下面的方法通过判断字符的类型来进行截取,效果还算可以:)


如果大家有其他的解决方法欢迎贴出来,共同学习:)
**********************************************************************
private String str;
private int counterOfDoubleByte;
private byte b[];
/**
* 设置需要被限制长度的字符串
* @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;
}


本文转贴自网友:focus2004 的文章
posted on 2005-08-12 15:39 Rosen 阅读(7969) 评论(15)  编辑  收藏 所属分类: Java EE 服务器端

评论

# re: 精确截取字符串(转载) 2005-08-19 08:27 ivan
if(b<0) 编译会出错。  回复  更多评论
  

# re: 精确截取字符串(转载) 2005-08-19 20:39 Rosen
马上修改一下代码,去年转贴的时候一直忘记修改了。
是 if(b[i] < 0),谢谢 ivan 指正。  回复  更多评论
  

# re: 精确截取字符串(转载) 2006-01-28 18:24 tdg
大作拜读,有一点愚见,特抛砖引玉:
1。字符串除了可以基于byte[]操作外,还可以基于char[]操作。看老大你的意图是想截取字符串的前几个字符然后加上省略符号最后输出而已,完全不必考虑用byte[]数组操作啊 。而且好像开发中更注重语义上的第几个字符而不是你说的这种情况哦。
2。以下是拙作,请斧正:
/**
* 字符串截取函数
* @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;
//如果字符串的位数小于等于要截取的位数,附加上表示省略的信息的字符串后返回
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;
}
}  回复  更多评论
  

# re: 精确截取字符串(转载) 2006-01-28 20:03 Rosen
呵呵 tdg 兄很认真喔,谈不上斧正。主要是这个问题,用 char 处理,如果是字母或者数字,实际上截取出来的会比汉字少占用一半的空间,所以截取出来后,还是不能对齐。而实际上 char 数组中,不管是字母、数字还是汉字,它们都只代表一个单元。但是 byte 则不同,字母、数字只占用一个字节,而汉字占用两个字节(都是GBK编码)。  回复  更多评论
  

# re: 精确截取字符串(转载) 2006-03-24 10:49 istarliu
您好!
你的文章让我受益不少,有个问题想向您确认一下:
在代码中
b = str.getBytes("GBK");
if(b.length <= len)
return str;
for(int i = 0; i < len; i++){
if(b[i] < 0)
counterOfDoubleByte++;
}
是不是如果只要是中文汉字,在b[i]对应的值都是小于0的,
也就是说,在汉字代表的两个字节中,这两个汉字分别转化为整数值时,是不是一定小于0,但值范围不能小于-127的。做过测试,不能肯定。:)

  回复  更多评论
  

# re: 精确截取字符串(转载) 2006-03-30 17:42 Rosen
istarliu,这里要强调一下,GBK、GB2312 双字节编码字节才是负的。UTF-8 三字节编码未去核实。  回复  更多评论
  

# re: 精确截取字符串(转载) 2007-01-19 16:28 lyazure
无意义的做法, 犯了常识错误, java内部表示任何字符都是16位, 而且不涉及输入输出操作不需要字符解码编码操作.不知道文中的"单纯地判断字符数效果并不理想"的结论如何得出,恐怕只是臆断.事实上只需根据字符数截取即可.
public String getLimitLengthString(String srcString, int expectLength){
if(srcString.length() <= expectLength) return srcString;
return srcString.subString(0, expectLength);
}  回复  更多评论
  

# re: 精确截取字符串(转载) 2007-01-19 23:19 Rosen
@lyazure
我只想说一句,请验证后再回答,最好能打印在 html 页面中,然后混合汉字和数字输出,看看长短是否一致。  回复  更多评论
  

# re: 精确截取字符串(转载) 2007-01-20 07:08 lyazure
不知Rosen验证原文中代码用的是怎样的例子,能否可以提供一个我不能处理的字符串或者这样的情境?
从文中的涉及对字符解码操作来看, 接收到的参数字符串并未正确解码, 关键不在字符长度处理的问题.只需先对字符串进行正确解码.
String desString = new String(srcString.getBytes("ISO-8859-1"), "GBK");
之后所有字符操作都可以正常进行,不会出现字符长度问题.
另外,从文中的意义看来, 原文对字符的解码应当用ISO-8859-1,而不是GBK,当然,因为GBK向下兼容ISO-8859-1,因此从结果来说并没有问题.
之前的评论有些词语过激,希望Rosen不要往心里去. 但似乎Rosen的回答马上有针锋相对的味道,呵呵.希望是我多虑了.  回复  更多评论
  

# re: 精确截取字符串(转载) 2007-01-20 14:07 Rosen
@lyazure
还不是很激动,只是感觉本文的意思没有完全表达清楚,应该再加点描述,比如这样的例子:
字符串“中文中文2222”,当直接截取srcString.substring(0, 4)时,“中文中文”这四个字会正确打印出来,没错。不过如果我们把字符串改为“2222中文中文”,那么打印出来的应该是“2222”。
这个时候输出到 html 是这样的:
中文中文
2222

可以看到,虽然我都是截取的同样长度,但是页面却很不美观,长短不一,一个现实中的例子,当然也是我一直没有纠正过来的错误,http://www.cdcin.com,你看首页的“新闻信息”栏目,当出现标题有数字的情况时,就显得很不统一,参差不齐。

所以,这就是本文为什么要讨论按照编码规则来截取字符串的原因。当然,这样处理并不会彻底的解决不整齐,但是总会好些,比如哪天发布某条全是数字和字母的标题,那这种参差不齐就太严重了。  回复  更多评论
  

# re: 精确截取字符串(转载) 2007-01-20 18:38 lyazure
看来我理解错了,原来是为了获得一致的显示宽度.
  回复  更多评论
  

# 我的做法 2007-04-24 15:16 国家机器
/***
* 字符串的单个字符是否是汉字
* @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个英文字符和一个汉字占据的宽度一致;
*/
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 "";
}  回复  更多评论
  

# re: 精确截取字符串(转载) 2007-05-14 11:44 Rosen
@国家机器
呵呵,感谢贡献,你的做法更精确了。
  回复  更多评论
  

# re: 精确截取字符串(转载) 2016-08-18 17:22 JustPassoner
@国家机器
六六,认识你是我等荣幸,酒疯知己千杯烧...  回复  更多评论
  

# re: 精确截取字符串(转载) 2016-08-18 17:56 JustPassoner
string=goodStr(string); 这个方法 是干什么用处的?  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: