万万没想到之Java编码的问题

以为很简单的问题耗时一天,尚未有完美解决方案。。

解决方案以及分析参阅: 

http://www.360doc.com/content/13/0830/14/1073512_310953718.shtml

关键字:Java中文字符编码乱码详述

http://javarevisited.blogspot.com/2012/01/get-set-default-character-encoding.html

关键字: How to get and set default Character encoding or Charset in Java

详情待我慢慢道来。。。


项目需求: 解析java文件,从中获取package, class, method, testng的annotation等。

本来这个东西用ruby已经实现了,而且工作良好,但是因为平台的问题,非要重新用java实现。。。擦

自然而然找到了javaParser,用起来还是很顺手。

但是项目要求打包成可执行的jar文件,这就苦了我了。


把我们另外一个项目的拿过来做测试包,使用eclipse运行,完美无误。

但是打包之后通过命令行运行就是各种错误。

基本上就是遇到了中文,以色列语(希伯来语)的时候出的错误。

之前对java编码这块也不是很熟(常年用ruby, python解决这类字符串问题),真的不知道水能有tm这么深!


首先尝试读入和写入的编码。

先讲下IO流的转换过程。

从github上下载项目压缩包 -> 读入zipinputstream -> 然后将符合条件的文件(至少得是java吧,至少里面得有@Test吧)转换成inputstream传给JavaParser,然后由其解析。

错误就出在inputstream传给javaParser这块。

一开始一直以为是我转换到inputstream时的问题,然后使用utf-8从zipinputstream切到inputstream,然后将inputstream给javapaser, 同时给javaparser一个utf-8的参数让它按照这个编码读。。。

经过2个多小时的折腾,发现我擦,完全没用。

其间遇到状况是这样的: 使用utf-8吧,一部分文件解析失败。不使用吧,这些没问题了,另外一些突然又有问题了。。。

其间还遇到了utf-8还是utf8还是UTF-8的问题。。。


经过又1个多小时的折腾,发现还是没思路,然后找来大牛(因为很壮,跟牛很像)帮忙。


大牛的思路(等下你会看到也挺奇葩的,哈哈):

对,是编码的问题,那么我们看看这些文件都是什么类型的编码呢,我们按照类型进行读入不就行了?(这里完全正确!但是后面就给带偏了。。)

发现大部分文件是没有编码格式的,然后少部分是使用utf-8保存的。

思路就是如果没有格式的,我们使用最广泛能兼容的格式,用到了iosxxxx-15的一个格式,有格式的使用默认格式,当然就是utf-8了。

这下问题少了很多,但是还是有文件不能正确解析。

我们的要求是必须要全部兼容,因为涉及到很多个项目,不可能因为你的问题改人家项目的代码。哭。


解析来就到了好玩的地方了:我们把这些中文,希伯来语都删掉吧!

嗯?!好主意啊(我也是脑子进水了)。于是我们找到了

text.replaceAll("[^\\x00-\\x7F]", "")

这个可以替换掉所有非acsii码(待确定是不是这个意思,有熟知大叔请帮忙评论下,多谢多谢!)。

不错不错,这下子又解决了不少有问题的文件。

然后大牛要回家陪老婆过周末blabla就走掉了。。。


然后我继续继续努力吧(继续进水中。。)


慢慢发现这以后出的问题就不是解析语言的问题,而是突然发现经常会丢掉双引号。

比如正常的 String a = "bbb";就变成了 String a = "bbb;

这个就没办法了。。

等等,我想到一个好主意,正则表达式!(回想起来,惭愧的要撞墙自杀)


我试着将出现这类问题的line通过正则表达式判断出来,然后通过替换将双引号加上。

(说道这里发现一道不错的面试题:使用java如何判断在一个字符串里,特定单词的数量。 答案见最后)

然后

然后发现了这样的:

String s1 = "private String receipt	= \"特典が適用され、PayPalの領収書に表示されます;"; #分号前少一个双引

接着发现了这样的:

String s2 = "ppBtnPage.setAttributeValue(\"billing_first_name\", \"劉);"; <span style="font-family: Arial, Helvetica, sans-serif;">#括号前少一个双引</span>

我心想这就差不多了吧,这正则写的也够复杂了,我擦,理论上不应该这么玩啊。

终于当我看到还有这样的,我就崩溃了,严格意义上是脑子的水被清空了

String s3 = "@Test (testName=\"19947,groups={\"RQA_HK\", \"RQA_zh\", \"RQA_APAC\" },description=\"HSS SPARTA FLOW\")"; <pre code_snippet_id="451465" snippet_file_name="blog_20140815_2_725999" name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">#TMD字符串中间少一个双引</span>
 

终于醒悟过来了: 你读的时候编码就是错误的,不论你后面怎么改,底子都不是好。之所以会遇到丢双引号,就是因为解析的时候出错了,转换格式的时候双引就被当作非acsii字符删掉了。而且还是随机的。根本无规律可循!!!

终于明白为什么叫悟空了,脑子空了才能悟出东西来。


因为一直纠结为什么在eclipse下就能正常运行的问题,于是搜索了一下如何像eclipse一样强制按照UTF-8编码读取文件。

万万没想到,最后XX还是XXX了(好像就是这么说的吧,每集必备的台词)

万万没想到,最后问题还是被我解决了。

在可执行jar包前加上-Dfile.encoding=UTF-8之后,终于把所有文件全部解析成功。


长吁了一口气,发个短信告慰了下陪老婆的大牛这个问题我解决了,哇咔咔咔。

然后被大牛加了个需求(他是这活的主要负责人,我来帮忙的干活),把这个参数写到项目里,免得别人每次用还要重复输入。


好嘞!

心想赶紧干完这票,保存下今天的战果上传,然后发个周报给大boss,然后回家给加班的老婆做饭等老婆回家,一起吃饭看爸爸去哪儿。。。。


然后又经过了1个小时。。。


我擦,这尼玛不管用啊。

理论上(自认为是这样的,没有科学依据,大家手下留情)设置一个全局的file.encoding不就行了?

System.setProperty("file.encoding","UTF-8");

然后设置,发现运行还是出错,没道理啊。

然后这时候大牛来了,我说有个问题。。

大牛说你今天的问题权已经用完了,下周吧,呵呵呵呵。。。

我勒个去,心说我自己弄。。。哼哼哼哼


大牛过来了。

大牛说:你把这个加上不就行了(就我加的那个。。。)

然后我把功能的部分注释掉,只留了编码打印的代码给他看。

我说不行啊,你看加了这行之后,执行jar包,打印编码,还是默认的GBK。

等等。。

怎么可以了?变成UTF-8了。。。(是因为之前我使用eclipse运行的时候没有设置这个参数,直接从系统获取然后打印的,由于eclipse已经设置了默认是utf-8,所以在eclipse中自然就是UTF-8。但是jar包执行的时候还是系统默认的GBK. 当时我演示的时候把这个参数加上了,当然就起作用了)

好吧。待我把功能代码恢复下,然后看结果如何。。。


嗯???!!!改成utf-8了还是不工作啊,不工作。。

然后我又把-Dfile.encoding=UTF-8加上之后,又完美的工作了,工作了,了。。。


大牛看了看,2秒之后说,回家吧,我媳妇楼下等我呢。闪之。。。


暗暗鄙视之。。。。



然后收拾东西准备回家。。。


想到下周还要解决这个问题,然后搜索了下,获得了如上的参阅链接,晚点自己研究下。

然后写下了这篇曲折又有趣的debug经历。

你看到这篇文章发表的时间就是我下班的时间。


嗯,一天的时间+3个小时都没有搞定的问题。


嗯。。还在等老婆中,因为她已经下班回家在路上了。。。


在办公室。TT


参考关于file.encoding=UTF-8的资料

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

http://yang3wei.github.io/blog/2013/02/10/java-dfile-dot-encoding-equals-utf-8-gan-diao-luan-ma/


最后公布答案

问题: 使用java如何判断在一个字符串里,特定单词的数量

答案:使用split

因为java的split是支持正则的(不清楚哪个版本有的这个特性),所以我们可以讲我们需要查找的单词使用正则来进行匹配,兼容大小写的哦:)

split之后判断数组长度,将长度减1就是答案了

想到这个是因为我要判断这一行里引号的数量是不是偶数对。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值