当前位置: 首页 > news >正文

用Java实现按字节长度截取字符串的方法

Web应用程序在浏览器中显示字符串时,由于显示长度的限制,常常需要将字符串截取后再进行显示。但目前很多流行的语言,如C#、Java内部采用的都是 Unicode 16(UCS2)编码,在这种编码中所有的字符都是两个字符,因此,如果要截取的字符串是中、英文、数字混合的,就会产生问题,如下面的字符串:

String s  =   " a加b等于c,如果a等1、b等于2,那么c等3 " ;

  上面的字符串既有汉字,又有英文字符和数字。如果要截取前6个字节的字符,应该是”a加b等",但如果用substring方法截取前6个字符就成了"a 加b等于c"。产生这个问题的原因是将substring方法将双字节的汉字当成一个字节的字符(UCS2字符)处理了。要解决这个问题的方法是首先得到该字符串的UCS2编码的字节数组,如下面的代码如下:

byte [] bytes  =  s.getBytes( " Unicode " );

    由于上面生成的字节数组中前两个字节是标志位,bytes[0] = -2,bytes[1] = -1,因此,要从第三个字节开始扫描,对于一个英文或数字字符,UCS2编码的第二个字节是相应的ASCII,第一个字节是0,如a的UCS2编码是0  97,而汉字两个字节都不为0,因此,可以利于UCS2编码的这个规则来计算实际的字节数,该方法的实现代码如下:

     public   static  String bSubstring(String s,  int  length)  throws  Exception
    {

        
byte [] bytes  =  s.getBytes( " Unicode " );
        
int  n  =   0 //  表示当前的字节数
         int  i  =   2 //  要截取的字节数 ,从第3个字节开始
         for  (; i  <  bytes.length  &&  n  <  length; i ++ )
        {
            
//  奇数位置,如3、5、7等,为UCS2编码中两个字节的第二个字节
             if  (i  %   2   ==   1 )
            {
                n
++ //  在UCS2第二个字节时n加1
            }
            
else
            {
                
//  当UCS2编码的第一个字节不等于0时,该UCS2字符为汉字,一个汉字算两个字节
                 if  (bytes[i]  !=   0 )
                {
                    n
++ ;
                }
            }
        }
        
//  如果i为奇数时,处理成偶数
         if  (i  %   2   ==   1 )

        {
            
//  该UCS2字符是汉字时,去掉这个截一半的汉字
             if  (bytes[i - 1]  !=   0 )
                i 
=  i  -   1 ;
            
//  该UCS2字符是字母或数字,则保留该字符
             else
                i 
=  i  +   1 ;
        }

        
return   new  String(bytes,  0 , i,  " Unicode " );
    }

    下面代码使用了bSubstring方法:

String s  =   " a加b等于c,如果a等1、b等于2,那么c等3 " ;
System.out.println(bSubstring(s,
6 ));

    上面的代码截取的字符串是 "a加b等 "

相关文章:

  • Ocr识别开篇
  • 在安卓上运行TensorFlow:让深度学习进入移动端
  • NTFS权限
  • 一般杀毒软件检测病毒原理
  • 关于OleVariant类型的疑问???
  • 技术助力第三次革命
  • redis持久化之RDB
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • CAML语句 多条件and使用
  • 第二节 Windows Communication Foundation 基础概念
  • vista下sql2008不能在c盘建数据库
  • 编程的真实样子
  • 比特币亿万富翁出手拯救 OpenBSD
  • 弹出窗口生成器
  • VTK的学习资源
  • 【剑指offer】让抽象问题具体化
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • HTML-表单
  • java 多线程基础, 我觉得还是有必要看看的
  • Js基础知识(一) - 变量
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Making An Indicator With Pure CSS
  • Markdown 语法简单说明
  • PhantomJS 安装
  • Python 反序列化安全问题(二)
  • Redis在Web项目中的应用与实践
  • springMvc学习笔记(2)
  • 工作手记之html2canvas使用概述
  • 关于springcloud Gateway中的限流
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 你对linux中grep命令知道多少?
  • 《码出高效》学习笔记与书中错误记录
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • (Forward) Music Player: From UI Proposal to Code
  • (初研) Sentence-embedding fine-tune notebook
  • (二)windows配置JDK环境
  • (接口自动化)Python3操作MySQL数据库
  • (十八)三元表达式和列表解析
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • .net 微服务 服务保护 自动重试 Polly
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • .net通用权限框架B/S (三)--MODEL层(2)
  • ??eclipse的安装配置问题!??
  • @RequestBody与@ResponseBody的使用
  • @RunWith注解作用
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • @Valid和@NotNull字段校验使用
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)
  • [bzoj 3534][Sdoi2014] 重建
  • [C# 基础知识系列]专题十六:Linq介绍