截取字符串的函数 按照字节 中文判别
2015-11-05 22:20
411 查看
截取字符串的函数 按照字节
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”。分析
substring(beginIndex, endIndex) 是返回的字符,题目要求的是字节Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
UTF- 8 和 GBK
UTF- 8是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示。
[code]String x = "我"; System.out.println(x.getBytes("utf-8").length); System.out.println(x.getBytes("GBK").length); /** * 输出 * 3 * 2 */
[code]String s = "我ABC汗"; System.out.println(new String(s.getBytes("GBK"), "GBK")); 输出"我ABC汗" System.out.println(new String(s.getBytes(), "GBK")); 乱码 鎴慉BC姹� System.out.println(new String(s.getBytes(), "utf8")); 输出"我ABC汗" System.out.println(new String(s.getBytes("utf8"), "utf8")); 输出"我ABC汗" System.out.println(new String(s.getBytes(), "ascii")); ���ABC��� 可以看出默认使用 utf8 编码,然后 ascii 解码,英文正常,但是汉字是3个
分析
默认是utf8编码,所以不写没事。encode 和 decode 需要相同
记住 jvm 里面是 unicode,出来时候才会具体编码
解决方法
思路就是从 String 的每个字符 遍历,然后如果是中文的,就-2,如果是英文的,-1。String.valueOf(b[i]).getBytes().length > 1判断是否是中文
[code]static String split(String orignal, int count) { // count 表示多少个字节 // 1个中文字符是2个字节 char[] b = orignal.toCharArray(); // constructor need character's no, so <= byte's count StringBuilder sb = new StringBuilder(count); for (int i = 0; i < b.length; i++) { if (count <= 0) { break; } String temp = String.valueOf(b[i]); // System.out.println(temp + "->" + temp.getBytes().length); // Chinese character if (temp.getBytes().length > 1) { count -= 2; if (count < 0) { break; } } else { count--; } sb.append(temp); } return sb.toString(); }
改进方法
[code]static String otherSplit(String original, int count) { StringBuilder sb = new StringBuilder(); // 这儿是 count 和 i 两头并进 // i 每次都 +1 ,每次都会至少找到1个字符(英文1个,中文2个) // 如果是中文字符,count 就-1 // 对于半个中文 for (int i = 0; i < count - 1; i++) { char c = original.charAt(i); if (String.valueOf(c).getBytes().length > 1) { count--; } sb.append(c); } return sb.toString(); }
方法有问题
[code]String s = "我ABCD爱哈BAC汗"; System.out.println(otherSplit(s, 6)); //我ABC System.out.println(split(s, 6)); //我ABCD
对于最后一个英文字符,会少一个字母
测试
[code]public static void main(String[] args) throws UnsupportedEncodingException { String s = "我额A爱哈BAC汗"; System.out.println(otherSplit(s, 2)); System.out.println(otherSplit(s, 3)); System.out.println(otherSplit(s, 4)); System.out.println(otherSplit(s, 5)); System.out.println(otherSplit(s, 6)); System.out.println(otherSplit(s, 9)); System.out.println(split(s, 2)); System.out.println(split(s, 3)); System.out.println(split(s, 4)); System.out.println(split(s, 5)); System.out.println(split(s, 6)); System.out.println(split(s, 9)); } /** 我 我 我额 我额 我额A 我额A爱哈 我 我 我额 我额A 我额A 我额A爱哈 */
判断是否是中文
[code]public static void main(String[] args) throws UnsupportedEncodingException { char c = '我'; System.out.println(Character.getNumericValue(c)); String s = String.valueOf(c); System.out.println(s.getBytes("utf8").length); System.out.println(s.getBytes("gbk").length); System.out.println(Arrays.toString(s.getBytes("utf8"))); System.out.println(Arrays.toString(s.getBytes("gbk"))); }/** -1 3 2 [-26, -120, -111] [-50, -46] */
可以通过 Character.getNumericValue 返回-1
也可以根据字节数,中文是多个字节,英文1个字节
根据字节得到的数字,中文是负数,英文和符号在0-256之间
getNumericValue() only applies to characters that represent numbers, such as the digits ‘0’ through ‘9’. As a convenience, it also treats the ASCII letters as if they were digits in a base-36 number system (so ‘A’ is 10 and ‘Z’ is 35).
相关文章推荐
- Arduino智能小车实践学习报告
- Java 继承 反汇编 class A { } 执行结果
- 对于2015长春赛的感想
- Struts2入门示例教程
- 遗忘的一些知识点
- Java的字符串连接符(+)
- 数据结构基础:二叉树,堆,多叉树
- 计算机一些基本进制单位及细节基础知识
- swift学习03_2
- ubuntu 设置ntp服务
- 从特征描述符到深度学习:计算机视觉发展20年
- Java文件操作(二)
- cell
- JVM类加载机制
- I2C驱动情景分析——怎样增加I2C设备
- leetcode-Single Number II
- 量化分析师的Python日记【第3天:一大波金融Library来袭之numpy篇】
- Android tips
- 大话频谱分析(三)
- linux:shell 编程 条件判断 以及 判断条件