一次java全角字符与半角字符转换优化
2015-11-27 20:30
399 查看
全角与半角
通常的英文字母、数字键、符号键都是半角的,半角的显示内码都是一个字节。而每个全角字符占用两个标准字符(或半角字符)位置半角字符是从33开始到126结束,与半角字符对应的全角字符是从65281开始到65374结束
其中较为特殊的是空格,半角的空格是32.对应的全角空格是12288
半角和全角的关系很明显,除空格外的字符偏移量是65248(65281-33 = 65248)
// 输入全角字符,输出半角字符 public static String QtoB(String input) { char c[] = input.toCharArray(); for (int i = 0; i < c.length; i++) { if (c[i] == '\u3000') { c[i] = ' '; } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { c[i] = (char) (c[i] - 65248); } } return new String(c); } // 半角转全角 public static String BtoQ(String input) { char c[] = input.toCharArray(); for (int i = 0; i < c.length; i++) { if (c[i] == ' ') { c[i] = '\u3000'; } else if (c[i] < '\177') { c[i] = (char) (c[i] + 65248); } } return new String(c); }
中间过程
项目中的需求是半角转成全角。最开始的需求是这样的,只针对指定的半角字符",.?!:;…~&@#'\"´〝〞()[]<>{}«»/|\\_¯ "进行转换。public static String BtoQ0(String str) { String s = ",.?!:;…~&@#'\"´〝〞()[]<>{}«»/|\\_¯ "; char[] c = str.toCharArray(); for (int i = 0; i < c.length; i++) { if (s.indexOf(c[i]) != -1) { if (c[i] == '<') { int j = i + 1; if (j < c.length && (c[j] == 'p' || c[j] == '/')) { int k1 = j + 1; if (k1 < c.length && (c[j] == 'p') && c[k1] == '>') { continue; } else if (k1 < c.length && (c[j] == '/') && c[k1] == 'p') { int k2 = k1 + 1; if (k2 < c.length && c[k2] == '>') { continue; } } } } else if (c[i] == '>') { int j = i - 1; if (j > 0 && c[j] == 'p') { int k1 = j - 1; if (k1 >= 0 && c[k1] == '<') { continue; } else if (k1 > 0 && c[k1] == '/') { int k2 = k1 - 1; if (k2 >= 0 && c[k2] == '<') { continue; } } } } else if (c[i] == '/') { int j = i - 1; if (j >= 0 && c[j] == '<') { int k1 = i + 1; if (k1 < c.length && c[k1] == 'p') { int k2 = k1 + 1; if (k2 < c.length && c[k2] == '>') { continue; } } } } if (c[i] == ' ') { c[i] = '\u3000'; } else { c[i] = (char) (c[i] + 65248); } } } return new String(c); }
需求后来又改成不要对完整的"<p></p>"过滤。最直接的过滤方式如下,最后直接用库函数replace一下:
public static String BtoQ1(String str) { String s = ",.?!:;…~&@#'\"´〝〞()[]<>{}«»/|\\_¯ "; char[] c = str.toCharArray(); int i = 0; while (i < c.length) { if (s.indexOf(c[i]) != -1) { if (c[i] == ' ') { c[i] = '\u3000'; } else { c[i] = (char) (c[i] + 65248); } } i++; } String result = new String(c); result = result.replace("<p>", "<p>").replace("</p>", "</p>"); return result; }
试想文本量那么多,replace也是很耗时的,最后优化的结果比上面快了5倍左右。如下:
public static String BtoQY(String str) { String s = ",.?!:;…~&@#'\"´〝〞()[]<>{}«»/|\\_¯ "; char[] c = str.toCharArray(); for (int i = 0; i < c.length; i++) { if (s.indexOf(c[i]) != -1) { if (c[i] == '<') { int j = i + 1; if (j < c.length) { int k1 = j + 1; if (k1 < c.length && (c[j] == 'p') && c[k1] == '>') { i += 2; continue; } else if (k1 < c.length && (c[j] == '/') && c[k1] == 'p') { int k2 = k1 + 1; if (k2 < c.length && c[k2] == '>') { i += 3; continue; } } } } if (c[i] == ' ') { c[i] = '\u3000'; } else { c[i] = (char) (c[i] + 65248); } } } return new String(c); }
相关文章推荐
- java Static解读以及public static void main(String[] args)详细分析
- 001 andorid 目录结构说明
- java Socket编程
- pipeline机制
- java URL的打开如果碰到203会自己重定向
- Java多线程学习笔记(一)
- 第二个spring冲刺第4天
- 深入分析 Java I/O 的工作机制
- Java大数处理
- Spring Web 单元测试实用HelloWorld(附代码)
- Java 结构体排序
- 解决Spring AOP Controller 不生效
- java hdu2088
- hadoop2.5.2 eclipse 插件编译
- eclipse 打开.java文件乱码
- 如何实现java 日期加减
- JAVA字符串转日期或日期转字符串
- java继承在程序中的运用
- MyBatis中$和#的区别
- 使用 Spring、Elasticsearch 及 Logstash 构建企业级数据搜索和分析平台