前言
在Java项目中,比如我们经常使用String的split方法对文本进行处理;在Map/Reduce中,我们也需要对HDFS文件读取后对line进行分割,也涉及到split。前几天,本来“好好的”程序,突然在split处报错,后来才知道由于有一条“脏数据”导致split“超出”了预期,才导致了“不可能发生的异常”就这样发生了~不过也说明了一些基础知识真的很重要,于是把String类的split源码阅读了下,发现一个“小小的”split也挺多内容的。
String中的split
在String中,split方法如下: 可见,split的核心在于Pattern.compile(regex).split(this, limit); Java提供Pattern,Matcher用于支持正则,可以看一个例子: 运行结果是: 0,1 || 3,4 |ab| 7,8 |cef| 8,9 || 11,12 |kk| 13,14 |a| 需要注意的是: 通过Pattern给定一个模式(regex),Matcher可以不断(find)匹配文本,并能找到每 一个匹配上的内容的开始(start),结束(end)索引【结束索引说白了,就是start+匹配 文本的长度】。 subSequence(begin,end)是一个“包头不包尾”的方法 问题: 在上面的while中,我们能到达的最大的索引处,就是最后一个end,而注意到很有可能 这个end之后还有内容,那么该如何处理呢? 如果一个正则将文本split成了几部分,我们只需要一部分呢? 如果分成的部分中有“”空字符串,split又是如何处理的? 我们可以带着这些问题来看看源码: 首先来看,limit对matchLimited的影响: limit < 0 或者 split(regex)等价于split(regex,0) ==> matchLimited:false limit > 0 ==> matchLimited:true 其实,while的意思就是说,如果limit>0的话,matchList只加入有限的内容。 如果整个文本没有匹配上,那么返回一个长度为1,内容为其本身的数组。 如果limit为0,那么会将最后匹配的那些空串删除掉直至非空串为止在返回结果。 |
结论
在实际应用中,我们一般使用这样的:
str.split(",") 此时limit=0,只需要注意会去掉最后的空串即可
str.split(",",-1) 此时会保留最后的空串
str.split(",",2) 限制匹配的个数,同时保留最后的空串
本文转自zfz_linux_boy 51CTO博客,原文链接:http://blog.51cto.com/zhangfengzhe/1661091,如需转载请自行联系原作者