截取中英文混合文字方法

来源:互联网 发布:完美者解码mac 编辑:程序博客网 时间:2024/05/21 09:57

   java内核是unicode的,就连class文件也是,但是很多媒体,包括文件/流的保存方式是使用字节流的。因此java要对这些字节流经行转化。char是unicode的,而byte是字节。我们在写jsp页面时可能没注意到jsp作为回显终端,也是byte的,所以在从jsp页面中读取表单和写入数据(javabean)时要注意页面的编码.一个传统的解决方案是所有的应用包括页面编码设置/数据库编码设置都设定一致,比如gbk(gbk是gb2312的扩展集,支持的字符要多些)
     .现在又有个问题了,既然java内核是unicode的编码,那么字符串String lml="我爱金信桥tbs,tbs金信桥爱我"的长度应该是中文字符和英文字符的个数和,即lml.length()==17.好了,如果我们想截取长度为14的字符串,那么应该:lml.substring(0,13);返回"我爱金信桥tbs,tbs金".这没问题吧?但如果是应用中要求我们截取"固定回显长度"的字符串回显到JSP页面,那应该怎么办呢?
      所谓"固定回显长度"是指一个区域纯英文能显示x个,纯中文能显示x/2个.假设一个JSP页面中,有个表格,其中一列宽度为13个纯英文字符,我们想显示主题,主题可以为中文或英文.如果我们简单地设定了取前13个字符,那么在英文情况下是没问题的,能正确显示截取的前13个.但汉字呢?一个汉字要占两个英文的宽度的.所以取了13个汉字就超过了列的宽度,破坏了布局.那取6个字符好了!恩,这到是没破坏布局,但你不觉得英文的情况下浪费了一般的宽度么?哦,那就不好办了,中英文混合的串确实麻烦...
      我在做mail系统时,在邮件列表中有一列加上了正文的内容提示(前50个字符,有点类似gmail),内容是可以有中文和英文混合的,所以为了尽量提示多些,不能采用笨方法:直接取25个字符,保证中文没问题,英文浪费去吧~~~后来仔细研究了一下,可以这样解决:从字符串转换成byte,然后判断汉字的个数,是汉字就取占两个空,不是汉字就占一个空.这就是为什么一开始我要提提java中的byte<---->char,注意到这里有个trick,就是如果最后截取的是半个汉字,要丢弃掉!!否则,最后可能出现一个?号.
      用法:string str=substring(lml,14);System.out.println(str); 输出: 我爱金信桥tbs,
核心代码如下:

/**
      * 判断一个字符是Ascill字符还是其它字符(如汉,日,韩文字符)
      * 
      * 
@param char
      *             c, 需要判断的字符
      * 
@return
 boolean, 返回true,Ascill字符
     
*/

    
public static boolean isLetter(char c) {
        
int k = 0x80
;
        
return c / k == 0 ? true : false
;
     }

    
/**

      * 得到一个字符串的长度,显示的长度,一个汉字或日韩文长度为2,英文字符长度为1
      * 
      * 
@param String
      *             s ,需要得到长度的字符串
      * 
@return
 int, 得到的字符串长度
     
*/

    
public static int lengths(String s) {
        
if (s == null
)
            
return 0
;
        
char[] c =
 s.toCharArray();
        
int len = 0
;
        
for (int i = 0; i < c.length; i++
) {
             len
++
;
            
if (!
isLetter(c[i])) {
                 len
++
;
             }
         }
        
return
 len;
     }

    
/**

      * 截取一段字符的长度,不区分中英文,如果数字不正好,则少取一个字符位
      * 
      * 
@author patriotlml
      * 
@param
 String
      *             origin, 原始字符串
      * 
@param
 int
      *             len, 截取长度(一个汉字长度按2算的)
      * 
@return
 String, 返回的字符串
     
*/

    
public static String substring(String origin, int len) {
        
if (origin == null || origin.equals("")||len<1
)
            
return ""
;
        
byte[] strByte = new byte
[len];
        
if (len >
 lengths(origin)){
            
return
 origin;
        }
         System.arraycopy(origin.getBytes(), 
0, strByte, 0
, len);
        
int count = 0
;
        
for (int i = 0; i < len; i++
) {
            
int value = (int
) strByte[i];
            
if (value < 0
) {
                 count
++
;
             }
         }
        
if (count % 2 != 0
) {
             //len 
= (len == 1? ++len : --
len;
             --len;
         }
        
return new String(strByte, 0
, len);
     }

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 魅族手机未找到固件怎么办不用电脑 魅族手机触屏局部失灵怎么办 更新了魅蓝的新系统掉帧怎么办 手机后盖摔了一下凹了一个洞怎么办 魅族手机充电需要重启怎么办 网上预约好了但就诊卡丢了怎么办 如果魅族手机锁屏密码忘记了怎么办 魅族手机应用加密忘记密码了怎么办 小米电视盒子3s死机黑屏怎么办 小米note充电充不进去电怎么办 乐视手机otg功能用不了怎么办 小米4c手机玩王者荣耀卡怎么办 捡的小米6被锁了怎么办 小米5s手机玩穿越火线卡怎么办 苹果平板更新完系统登录不上怎么办 谷歌商店一直卡在核对信息怎么办 贴吧邮箱忘了无法登陆怎么办 华为手机绑定了账号忘了怎么办 淘宝的手机多次注册无法登录怎么办 电脑看不到U盘里面的文件怎么办 c盘访问权限被锁了怎么办 xp系统电脑开机密码忘记了怎么办 华为荣耀9用久了卡怎么办 华为p9相机模糊敲打就正常怎么办 华为p9蓝频按什么都没反映怎么办 华为手机p9开机密码忘了怎么办 华为P9手机开机一直闪屏怎么办 荣耀畅玩7x用户数据锁定怎么办 华为手机p9的指纹解锁坏了怎么办 华为P9青春版外放音量小怎么办 华为麦芒5的开关键失灵怎么办 小米手机进水黑屏但是有声音怎么办 小米5手机突然黑屏没电怎么办 小米4开不了机怎么办充电没反应 小米手机充电没反应开不了机怎么办 红米note手机开不了机怎么办 红米手机突然黑屏开不了机怎么办 红米2a开不开机怎么办 红米4手开不了机怎么办 红米4a开不了机怎么办 魅族手机拨打电话时黑屏怎么办