要求实现一个按字节截取字符串的方法,比如对于字符串"我ZWR爱JAVA",截取它的前四位字节应该是"我
ZW",而不是"我ZWR",同时要保证不会出现截取了半个汉字的情况。
英文字母和中文汉字在不同的编码格式下,所占用的字节数也是不同的,我们可以通过下面的例子来看看在一
些常见的编码格式下,一个英文字母和一个中文汉字分别占用多少字节。
package com.cmb.fmserver.business.direct.bankfront; import java.io.UnsupportedEncodingException; public class EncodeTest { /** * 打印字符串在指定编码下的字节数和编码名称到控制台 * * @param s * 字符串 * @param encodingName * 编码格式 */ public static void printByteLength(String s, String encodingName) { System.out.print("字节数:"); try { //如果你的EncodeTest类使用其他编码方式,替换这里的gbk为你的文件编码方式。 String ss = new String(s.getBytes("gbk"),encodingName); System.out.print(ss.getBytes(encodingName).length); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println(";编码:" + encodingName); } public static void main(String[] args) { String en = "A"; String ch = "人"; // 计算一个英文字母在各种编码下的字节数 System.out.println("英文字母:" + en); EncodeTest.printByteLength(en, "GB2312"); EncodeTest.printByteLength(en, "GBK"); EncodeTest.printByteLength(en, "GB18030"); EncodeTest.printByteLength(en, "ISO-8859-1"); EncodeTest.printByteLength(en, "UTF-8"); EncodeTest.printByteLength(en, "UTF-16"); EncodeTest.printByteLength(en, "UTF-16BE"); EncodeTest.printByteLength(en, "UTF-16LE"); System.out.println(); // 计算一个中文汉字在各种编码下的字节数 System.out.println("中文汉字:" + ch); EncodeTest.printByteLength(ch, "GB2312"); EncodeTest.printByteLength(ch, "GBK"); EncodeTest.printByteLength(ch, "GB18030"); EncodeTest.printByteLength(ch, "ISO-8859-1"); EncodeTest.printByteLength(ch, "UTF-8"); EncodeTest.printByteLength(ch, "UTF-16"); EncodeTest.printByteLength(ch, "UTF-16BE"); EncodeTest.printByteLength(ch, "UTF-16LE"); } }
运行结果如下:
英文字母:A
字节数:1;编码:GB2312
字节数:1;编码:GBK
字节数:1;编码:GB18030
字节数:1;编码:ISO-8859-1
字节数:1;编码:UTF-8
字节数:4;编码:UTF-16
字节数:2;编码:UTF-16BE
字节数:2;编码:UTF-16LE
中文汉字:人
字节数:2;编码:GB2312
字节数:2;编码:GBK
字节数:2;编码:GB18030
字节数:2;编码:ISO-8859-1
字节数:6;编码:UTF-8
字节数:4;编码:UTF-16
字节数:2;编码:UTF-16BE
字节数:2;编码:UTF-16LE
UTF-16BE和UTF-16LE是UNICODE编码家族的两个成员。UNICODE标准定义了UTF-8、UTF-16、UTF-32三
种编码格式,共有UTF-8、UTF-16、UTF-16BE、UTF-16LE、UTF-32、UTF-32BE、UTF-32LE七种编码方
案。JAVA所采用的编码方案是UTF-16BE。从上例的运行结果中我们可以看出,GB2312、GBK、GB18030三
种编码格式都可以满足题目的要求。下面我们就以GBK编码为例来进行解答。
如果我们直接按照字节截取会出现什么情况呢?我们来测试一下:
public class CutString { public static void main(String[] args) throws UnsupportedEncodingException { String s = "我ZWR爱JAVA"; // 获取GBK编码下的字节数据 byte[] data = s.getBytes("GBK"); byte[] tmp = new byte[6]; // 将data数组的前六个字节拷贝到tmp数组中 System.arraycopy(data, 0, tmp, 0, 6); // 将截取到的前六个字节以字符串形式输出到控制台 s = new String(tmp); System.out.println(s); } }
输出结果:
1. 我ZWR?
在截取前六个字节时,第二个汉字“爱”被截取了一半,导致它无法正常显示了,这样显然是有问题的。
我们不能直接使用String类的substring(int beginIndex, int endIndex)方法,因为它是按字符截取
的。'我'和'Z'都被作为一个字符来看待,length都是1。实际上我们只要能区分开中文汉字和英文字母,这个问
题就迎刃而解了,而它们的区别就是,中文汉字是两个字节,英文字母是一个字节。
public class CutString { /** * 判断是否是一个中文汉字 * * @param c * 字符 * @return true表示是中文汉字,false表示是英文字母 * @throws UnsupportedEncodingException * 使用了JAVA不支持的编码格式 */ public static boolean isChineseChar(char c) throws UnsupportedEncodingException { // 如果字节数大于1,是汉字 // 以这种方式区别英文字母和中文汉字并不是十分严谨,但在这个题目中,这样判断已经足够了 return String.valueOf(c).getBytes("GBK").length > 1; } /** * 按字节截取字符串 * * @param orignal * 原始字符串 * @param count * 截取位数 * @return 截取后的字符串 * @throws UnsupportedEncodingException * 使用了JAVA不支持的编码格式 */ public static String substring(String orignal, int count) throws UnsupportedEncodingException { // 原始字符不为null,也不是空字符串 if (orignal != null && !"".equals(orignal)) { // 将原始字符串转换为GBK编码格式 orignal = new String(orignal.getBytes(), "GBK"); // 要截取的字节数大于0,且小于原始字符串的字节数 if (count > 0 && count < orignal.getBytes("GBK").length) { StringBuffer buff = new StringBuffer(); char c; for (int i = 0; i < count; i++) { // charAt(int index)也是按照字符来分解字符串的 c = orignal.charAt(i); buff.append(c); if (CutString.isChineseChar(c)) { // 遇到中文汉字,截取字节总数减1 --count; } } return buff.toString(); } } return orignal; } public static void main(String[] args) { // 原始字符串 String s = "我ZWR爱JAVA"; System.out.println("原始字符串:" + s); try { System.out.println("截取前1位:" + CutString.substring(s, 1)); System.out.println("截取前2位:" + CutString.substring(s, 2)); System.out.println("截取前4位:" + CutString.substring(s, 4)); System.out.println("截取前6位:" + CutString.substring(s, 6)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
运行结果:
1. 原始字符串:我ZWR爱JAVA
2. 截取前1位:我
3. 截取前2位:我
4. 截取前4位:我ZW
5. 截取前6位:我ZWR爱
相关推荐
关于java按字节截取带有汉字的字符串的解法.不错的一个程序。我也是从高手那拿来的,觉得不错,传上来给感兴趣的朋友学习学习。
截取含有中英文的字符串,按字节进行截取,当出现汉字时不能截取半个汉字要把汉字补全。
字符串截取,按字节截取字符串,截取字符串帮助类
下面小编就为大家带来一篇java按字节截取带有汉字的字符串的解法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
实现一个按字节来截取字符串的方法,功能类似于string类的substring方法,String类是按字符截取 的,例如"中国abc".substring(1,3),将返回...要求按字节截取,一个英文字符当一个字节,一个中文字符当两个字节.
7. 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉...
最近需要用到按字节数截取字符串。在网上找了很多方法。 Encoding.Default.GetString采用的Default Encoding.UTF8.GetBytes采用的是utf-8编码。这样当然是乱码。尤其出现中文时候。 对这类数据处理当然要用统一的...
oracle中的substr是针对字节进行截取,当处理对中文汉字时,非常不方便,通过对其封装,可以实现对字符进行截取。
根据指定字节数截取字符串,当指定处为中文第一个字节时少截取一个字符,当长度大于指定截取长度时,截取后在字符串末尾追加指定字符串 * 这里添加了字符串的编码,因为页面的编码不同,字符串所占字节
指定截取字节数,截取字符串,但是不能出现半个汉字的情况,例如: 字符串"喊sd中d王",长度2byte为:喊,长度3byte为:喊s,长度4byte为:喊sd,长度5byte为:喊sd,长度6byte为:喊sd中
//中文截取2,单字节截取模式 function cn_substr($str,$slen,$startdd=0){ $restr = “”; $c = “”; $str_len = strlen($str); if($str_len < $startdd+1) return “”; if($str_...
做过大型网站前台的Web开发程序员最头疼的事情就是前台首页的布局,这其中最最头疼的就是标题字符的截取的问题,虽然有fn:substring,但表现率以及对中文的支持均不够完善,其实最终还是归结为客户要求太高了,不过...
但字符串只要出现中文字符,就有可能导致PHP substr中文乱码,因为中文UTF-8编码,每个汉字占3字节,而GB2312占2字节,英文占1字节,截取位数不准确,substr()硬生生地将一个中文字符“锯”成两半,造成断开的字符会...
TIA博途中字符串转换相关指令的使用方法(一)
7、编程:编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我...
Java 按照字节来截取字符串的工具,不会出现半个汉字。一个中文两个字节,一个英文字符只占 1 个字节** 1. 通常我们用于前端显示的时候,防止标题过长
JavaScript字符串处理函数,根据定义的长度截取字符串,超出部分裁掉追加……,很多时候网页上显示的内容需要缩成“…”该方法用于处理字符串显示固定长度,超长部分用“…”代替: /**参数说明: * 根据长度截取...
字符串截取函数,只限单字节字符使用(对于中文的截取时遇上奇数长度是会出现乱码,需另行处理),本函数可截取字符串指定范围内的字符。
根据显示长度截取字符串,之前php用的utf8编码,10个英文和10个汉字的显示长度差距太大,按字节截取的话又会出错出现截取半个汉字的情况,所以写了这两个函数. 这两天在折腾golang,所以就用golang重写了着连个函数.代码...