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

向C#的String类添加按字节截取字符串的扩展方法

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  =  System.Text.Encoding.Unicode.GetBytes(s);
    然后从第一个字节开始扫描,对于一个英文或数字字符,UCS2编码的第一个字节是相应的ASCII,第二个字节是0,如a的UCS2编码是97  0,而汉字两个字节都不为0,因此,可以利于UCS2编码的这个规则来计算实际的字节数,为了更方便,将按字节长度截取字符串的方法注册为String类的扩展方法,实现代码如下: 
public   static   class  StringExt
{

    
public   static  String bSubstring( this   string  s,  int  length)
    {
        
byte [] bytes  =  System.Text.Encoding.Unicode.GetBytes(s);
        
int  n  =   0 ;   //   表示当前的字节数
        
int  i  =   0 ;   //   要截取的字节数
        
for  (; i  <  bytes.GetLength( 0 &&  n  <  length; i ++ )
        {
             //   偶数位置,如0、2、4等,为UCS2编码中两个字节的第一个字节
             if  (i  %   2   ==   0 )
            {
                n
++ ;        //   在UCS2第一个字节时n加1
            }
            
else
            {
               //   当UCS2编码的第二个字节大于0时,该UCS2字符为汉字,一个汉字算两个字节
                 if  (bytes[i]  >   0 )
                {
                    n
++ ;
                }
            }
        }
         //   如果i为奇数时,处理成偶数
         if  (i  %   2   ==   1 )
        { 
              //   该UCS2字符是汉字时,去掉这个截一半的汉字
             if  (bytes[i]  >   0 )
                i  =  i  -   1 ;
             //   该UCS2字符是字母或数字,则保留该字符
             else
                i 
=  i  +   1 ;
        }

         return  System.Text.Encoding.Unicode.GetString(bytes,  0 , i);
    }
}
     在上面的代码中,如果最后要截取奇数个字符(以字节为单位),并且当最后一个字符是字母或数字,则保留该字符,如果是汉字,说明这个汉字被截了一半,则去掉这个汉字。
     可以使用下面的代码来截取字符串:
String subStr  =  s.bSubstring( 6 );   //   substr的值是"a加b等" 

 本文转自 androidguy 51CTO博客,原文链接:http://blog.51cto.com/androidguy/214973,如需转载请自行联系原作者

相关文章:

  • 根据要素选择集,创建新图层
  • windows2003建立隐藏管理员用户
  • Hbase 之 HBase 的整体架构
  • AgileEAS.NET之敏捷并行开发方法
  • Zabbix监控屏幕全屏显示多个监控项
  • 脚本1-38
  • python之通过“反射”实现不同的url指向不同函数进行处理(反射应用一)
  • Bash技巧总结
  • 关于vector性能的测试(一)
  • 重装linux服务器后开不了机
  • Linux TC的ifb原理以及ingress流控
  • linux--mariadb数据库
  • nginx开启后主机无法访问虚拟机的nginx解决方案
  • Linux 特殊目录
  • MPLS TE第一步:创建基本TE隧道
  • @angular/forms 源码解析之双向绑定
  • 【前端学习】-粗谈选择器
  • 10个最佳ES6特性 ES7与ES8的特性
  • centos安装java运行环境jdk+tomcat
  • CSS实用技巧干货
  • iOS小技巧之UIImagePickerController实现头像选择
  • JAVA_NIO系列——Channel和Buffer详解
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • JS 面试题总结
  • JS笔记四:作用域、变量(函数)提升
  • js递归,无限分级树形折叠菜单
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • php ci框架整合银盛支付
  • session共享问题解决方案
  • SOFAMosn配置模型
  • 阿里研究院入选中国企业智库系统影响力榜
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 从0到1:PostCSS 插件开发最佳实践
  • 浅谈web中前端模板引擎的使用
  • 推荐一个React的管理后台框架
  • 小程序开发之路(一)
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 湖北分布式智能数据采集方法有哪些?
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • 树莓派用上kodexplorer也能玩成私有网盘
  • # Panda3d 碰撞检测系统介绍
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (1)常见O(n^2)排序算法解析
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (Java数据结构)ArrayList
  • (LeetCode C++)盛最多水的容器
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (图)IntelliTrace Tools 跟踪云端程序
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转载)Google Chrome调试JS
  • .NET 回调、接口回调、 委托
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)