博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
向C#的String类添加按字节截取字符串的扩展方法
阅读量:7079 次
发布时间:2019-06-28

本文共 1425 字,大约阅读时间需要 4 分钟。

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,如需转载请自行联系原作者
你可能感兴趣的文章
Linux系统编程——进程间通信:信号中断处理
查看>>
安全管道工具SSF
查看>>
第十一章 非对称加密算法--DH
查看>>
详解 Tomcat 的连接数与线程池
查看>>
【转】TCP分段与IP分片
查看>>
iOS 多线程 NSOperation、NSOperationQueue
查看>>
delphi执行查询语句时的进度条怎么做
查看>>
CF 335A(Banana-贪心-priority_queue是大根堆)
查看>>
python的memcache使用如果对key设置了一个int型
查看>>
Leetcode: Longest Substring with At Most Two Distinct Characters
查看>>
173. Binary Search Tree Iterator
查看>>
《让LoadRunner走下神坛》
查看>>
[python基础知识]python内置函数map/reduce/filter
查看>>
基因家族收缩和扩张分析 & Selective loss pathway & 泛基因组
查看>>
HDU2089 ------不要62(数位dp)
查看>>
hdu4756 Install Air Conditioning(MST + 树形DP)
查看>>
MusicXML 3.0 (19) - 八度
查看>>
【android】动画效果研究(PopupWindow)【4】
查看>>
查看Eclipse版本号的方法
查看>>
onclik的使用.
查看>>