`
剑锋凛冽
  • 浏览: 75545 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Java的split一定切割字符串吗?

 
阅读更多

先看下面的代码

 

String test="www.baidu.com";
		String[] result=test.split(".");
		System.out.println(Arrays.toString(result));

 初一看,输出结果肯定是[www,baidu,com]

但是,实际上的输出结果却是[],Why?

仔细查看一下String的API说明就可以发现split(String regex),奥秘就在这里,split使用正则表达式作为参数,而"."在正则表达式中表示任意字符,因此最后没有任何结果也就可以相见了。

类似的String的API还有matches,replaceAll,replaceFirst。

在String的API中,还有一对很奇怪的API:replace和replaceAll,只从名字看,replaceAll是replace的复数形式,但实际上二者都是用于替换字符串中所有匹配的字符串,只不过replace用普通字符串作参数,而replaceAll用正则表达式作参数

 

//split使用的是正则表达式作为参数
		String test="www.baidu.com";
		String temp1=test.replace(".", "\\");//这里的\\是用于转义\符号
		//第一个正则表达式参数中,\\.将会被转义成\.
		//第二个实际上是前两个\\用于生成转义用的\,而后两条用于生成字符\
		String temp2=test.replaceAll("\\.", "\\\\");
		System.out.println("replace的结果:"+temp1);
		System.out.println("replaceAll的结果:"+temp2);
 

上面的代码,temp1和temp2的值是相同的

在temp2的实现过程中为什么用了4个\而不是temp1的2个\呢,这是因为虽然replace、replaceAll在底层都是通过Matcher类的replaceAll函数实现的,但是replace在调用之前调用过toString,将转义过程提前了,而replaceAll实际上是在Matcher类实现replaceAll的过程中才进行转义字符的处理。在Matcher的实现中如下:第16行程序中,读到"\\"时,自动向下扫描,如果只有2个\,将会出现StringIndexOutOfBoundsException异常

 

 public Matcher appendReplacement(StringBuffer sb, String replacement) {

        // If no match, return error
        if (first < 0)
            throw new IllegalStateException("No match available");

        // Process substitution string to replace group references with groups
        int cursor = 0;
        String s = replacement;
        StringBuffer result = new StringBuffer();

        while (cursor < replacement.length()) {
            char nextChar = replacement.charAt(cursor);
            if (nextChar == '\\') {
                cursor++;
                nextChar = replacement.charAt(cursor);
                result.append(nextChar);
                cursor++;
            } else if (nextChar == '$') {
                // Skip past $
                cursor++;

                // The first number is always a group
                int refNum = (int)replacement.charAt(cursor) - '0';
                if ((refNum < 0)||(refNum > 9))
                    throw new IllegalArgumentException(
                        "Illegal group reference");
                cursor++;

                // Capture the largest legal group string
                boolean done = false;
                while (!done) {
                    if (cursor >= replacement.length()) {
                        break;
                    }
                    int nextDigit = replacement.charAt(cursor) - '0';
                    if ((nextDigit < 0)||(nextDigit > 9)) { // not a number
                        break;
                    }
                    int newRefNum = (refNum * 10) + nextDigit;
                    if (groupCount() < newRefNum) {
                        done = true;
                    } else {
                        refNum = newRefNum;
                        cursor++;
                    }
                }

                // Append group
                if (group(refNum) != null)
                    result.append(group(refNum));
            } else {
                result.append(nextChar);
                cursor++;
            }
        }
分享到:
评论
Global site tag (gtag.js) - Google Analytics