美文网首页Javajava学习
java字符串切割

java字符串切割

作者: 背影杀手不太冷 | 来源:发表于2016-06-24 10:34 被阅读4379次

    标签(空格分隔): java


    方法一:split() 方法——JDK 1.4 or later##

    例子:

    public class StringSplit {
        public static void main(String[] args) {
        //一般用法
            String sourceStr = "1,2,3,4,5";
            String[] sourceStrArray = sourceStr.split(",");
            for (int i = 0; i < sourceStrArray.length; i++) {
                System.out.println(sourceStrArray[i]);
            }
    
            // 限定最多分割出3个字符串
            int maxSplit = 3;
            sourceStrArray = sourceStr.split(",", maxSplit);
            for (int i = 0; i < sourceStrArray.length; i++) {
                System.out.println(sourceStrArray[i]);
            }
        }
    }
    //输出结果:
    1
    2
    3
    4
    5
    1
    2
    3,4,5
    

    分隔符如果用到一些特殊字符,可能会得不到我们预期的结果。在正则表达式中有特殊的含义的字符,我们使用的时候必须进行转义

    public class StringSplit {
        public static void main(String[] args) {
            String value = "192.168.128.33";
            // 注意要加\\,要不出不来,yeah
            String[] names = value.split("\\.");
            //String[] output = test.split(Pattern.quote("."));
            //使用 \\ 跟使用Pattern.quote的效果一样
            for (int i = 0; i < names.length; i++) {
                System.out.println(names[i]);
            }
        }
    }
    //转义字符总结
    1.字符 "|"  "*"  "+"  "."  "," 在正则表达式中用\\.表示,或者用Pattern.quote方法表示。
    2.而如果是"\",那么就得写成"\\\\"。
    3.如果一个字符串中有多个分隔符,可以用"|"作为连字符。
    

    字符串中有多个分隔符,可以用"|"作为连字符的例子:

    public static void main(String[] args)
        {
                
                String str ="Java string-split#test";
                String[] sourceStrArray = str.split(" |-|#");
     //注意上面的(" |-|#")的一开始的字符就是空格,看上去好像没写一样喔
                for (int i = 0; i < sourceStrArray.length; i++) {
                    System.out.println(sourceStrArray[i]);
                }
        }
    

    有时在分割字符串之前需要对字符串进行一些检查,如:

    public static void main(String[] args)
    {
    
            String test = "abc.def.123";
            //开始检查
            if(test.contains(".")){
                 String[] output = test.split("\\.");
                 //第二次检查
                    if(output.length!=3){
    throw new IllegalArgumentException(test + " - invalid format!");
                     }else{
                        System.out.println(output[0]);
                        System.out.println(output[1]);
                        System.out.println(output[2]);
                            }
                    }else{
    throw new IllegalArgumentException(test + " - invalid format!");
                    }
                    
            }
    

    高级用法:结合正则表达式
    但是使用正则的话,效率肯定是有问题的

    public class Test01 {  
        public static void main(String[] args) {  
            String str = "one123";  
            String regex = "(?<=one)(?=123)";  
            // String regex = "(?<=one)"; 效果和上面的那句一样
            String[] strs = str.split(regex);  
            for(int i = 0; i < strs.length; i++) {  
                System.out.printf("strs[%d] = %s%n", i, strs[i]);  
            }  
        }  
    }  
    结果输出:
    strs[0] = one
    strs[1] = 123
    为什么呢?表示对正则表达式不是太懂????
    

    方法二:StringTokenizer ——从JDK1.0开始便可以使用StringTokenizer,JDK1.4开始才有String.split()。

    注意:StringTokenizer是老版本对方法,因为兼容性的原因不鼓励使用,推荐使用String.split()。但是StringTokenizer效率高,在后文的三种方法的比较中会说到

    简单用法例子:

    public static void main(String[] args) {
         String test = "abc.def.123";
          StringTokenizer token = new StringTokenizer(test, ".");
                while (token.hasMoreTokens()) {
                 //利用循环来获取字符串str1中下一个语言符号
                    System.out.println(token.nextToken());
                }
            }
    输出结果:
    abc
    def
    123
    

    格外注意:对于两个分隔符之间的空字符串会忽略。例如:

     public static void main(String[] args) {
           String ip = "192.168.123..33";//两个点之间是空字符串
    //   String ip = "192.168.123. .33";//两个点之间是空格
            StringTokenizer token=new StringTokenizer(ip,".");  
            while(token.hasMoreElements()){
    //注意这里用的是hasMoreElements()跟hasMoreTokens()效果一样
             System.out.print(token.nextToken()+"  ");  
            } 
    
        }
    输出结果:192  168  123  33 //注意"192.168.128...33"中间的...这三个点中间是有两个空字符串,是空字符串,而不是空格喔!!因为是空字符串,所以切出来的也是空,什么都没有
    

    例子二:
    int num1 = strT1.countTokens();//获取字符串str1后的个数
    hasMoreElements()跟hasMoreTokens()效果一样
    String nextToken()
    返回此 string tokenizer 的下一个标记。
    String nextToken(String delim)
    返回此 string tokenizer 的字符串中的下一个标记。

    public static void main(String[] args)
        {
                String str1 = "Hello world!This is Java code,stringTokenizer Demo.";
                //声明并初始化字符串str1
                String str2 = "How to use StringTokenizer?StringTokenizer?";
                //声明并初始化字符串str2
                StringTokenizer strT1 = new StringTokenizer(str1," ,.!");
                //创建StringTokenizer类的对象strT1,并构造字符串str1的分析器
                //以空格符、","、"."及"!"作为定界符
                StringTokenizer strT2 = new StringTokenizer(str2," ?");
                //创建StringTokenizer类的对象strT2,并构造字符串str2的分析器
                //以空格符及"?"作为定界符
                int num1 = strT1.countTokens();
                //获取字符串str1中语言符号的个数
             int num2 = strT2.countTokens();
                //获取字符串str2中语言符号的个数
                System.out.println("str1 has "+num1+" words.They are:");
                while(strT1.hasMoreTokens())
                {   //利用循环来获取字符串str1中下一个语言符号,并输出
                       String str = strT1.nextToken();
                       System.out.print("\""+str+"\" ");
                }
                System.out.println("\nstr2 has "+num2+" words.They are:");
                while(strT2.hasMoreElements())
                {   //利用循环来获取字符串str2中下一个语言符号,并输出
                        String str = strT2.nextToken();
                       System.out.print("\""+str+"\" ");
                }
        }
    

    注意还有一个一个参数的StringTokenizer(String str)构造方法
    使用默认的定界符,即空格符(如果有多个连续的空格符,则看作是一个)、换行符、回车符、Tab符号等
    例子;

        String str1 ="A B   \nC";//情况一C,将空格符、换行符作为定界符,多个连续的空格符,则看作是一个
        //String str1 ="A B   \\nC";情况二,在情况一的基础上将换行符用“\”转义了
        StringTokenizer strT1 = new StringTokenizer(str1);
         while(strT1.hasMoreTokens())
            {   //利用循环来获取字符串str1中下一个语言符号,并输出
                       String str = strT1.nextToken();
                       System.out.print("'"+str+"'");
                }
    输出结果:情况一:'A''B''C'
              情况二:'A''B''\nC'
    

    方法三:使用String的两个方法—indexOf()和subString()——subString()是采用了时间换取空间技术,因此它的执行效率相对会很快,只要处理好内存溢出问题,但可大胆使用。而indexOf()函数是一个执行速度非常快的方法##

    1、substring(int begin);截取掉s从首字母起长度为begin的字符串,将剩余字符串赋值给s;

     String text ="我爱你";
                String temp= text.substring(1);
                System.out.println(temp); 
    输出:爱你
    

    2、substring(int begin,int end);截取s中从begin开始至end结束时的字符串,并将其赋值给s;注意:不包括end

      String text ="我爱你们";
                String temp= text.substring(0,2);
                System.out.println(temp); 
    输出:我爱
    

    3、indexOf(subString[, startIndex])返回 String 对象内第一次出现子字符串的字符位置。 如果没有找到子字符串,则返回 -1。
    subString 必选项。要在 String 对象中查找的子字符串。
    starIndex 可选项。该整数值指出在 String 对象内开始查找的索引。如果省略,则从字符串的开始处查找。

    额外注意的:charAt():charAt()方法可用来获取指定位置的字符串,index为字符串索引值,从0开始到string.leng - 1,若不在这个范围将返回一个空字符串

    var str = 'abcde';
    console.log(str.charAt(2));        //返回c
    console.log(str.charAt(8));        //返回空字符串
    

    lastIndexOf()语法与indexOf()类似,它返回的是一个指定的子字符串值最后出现的位置,其检索顺序是从后向前。

    将indexOf()和subString()结合来截取的例子

    //这个做法十分巧妙
    public static void out(){
            String str = "我爱你们,你爱他,他爱她们加一,她爱他";  
    //因为不知道到底截取完之后有多少个,所以用集合保存
            List  stringList =new ArrayList<String>();
            String temp = str;  
                while (true) {  
                    String splitStr = null; 
                    int index = temp.indexOf(",");  
                    if (index < 0) {  
                        break;  
                    }  
                    splitStr = temp.substring(0, index);  
                    System.out.println(splitStr);
                    stringList.add(splitStr);
                    temp = temp.substring(index + 1);  
                }  
        } 
    

    如果十分有规律的话,也可以像下面这样做


    此处输入图片的描述此处输入图片的描述

    上面的做法虽然是可以但是有点笨,其实可以有聪明点的做法:

    适合情况:当分隔符是一个字符时
    private static List<String> split2( final String str )
    {
        final List<String> res = new ArrayList<String>( 10 );
        int pos, prev = 0;
        while ( ( pos = str.indexOf("" + m_separatorChar, prev ) ) != -1 )
        {
            res.add( str.substring( prev, pos ) );
            prev = pos + 1; // start from next char after separator
        }
        res.add( str.substring( prev ) );
        return res;
    }
    
    适合情况:当分隔符是多个字符时
    private static List<String> split( final String str )
    {
        final List<String> res = new ArrayList<String>( 10 );
        int pos, prev = 0;
        while ( ( pos = str.indexOf( m_separator, prev ) ) != -1 )
        {
            res.add( str.substring( prev, pos ) );
            prev = pos + m_separator.length(); // start from next char after separator
        }
        res.add( str.substring( prev ) );
        return res;
    }
    

    三种方法的比较:##

    1、String.split(String.split是用正则表达式匹配,所以不使用KMP字符串匹配算法)用的都是按顺序遍历的算法,时间复杂度O(m*n),较高,所以性能上,StringTokenizer好很多,对于频繁使用字符串分割的应用,例如etl数据处理,使用StringTokenizer性能可以提高很多。

    2、在split需要被大量调用的场合,在现有的Android VM里面,String类的split方法肯定是不符合要求的,StringTokenizer是最廉价的替换split的方法,简单修改成这个实现之后,花费时间能提升一个数量级

    3、indexOf结合subString经过充分的优化,对于结构化特别是表格类的数据,效率是最快的

    Java 字符串操作常用的各种的方法

    相关文章

      网友评论

        本文标题: java字符串切割

        本文链接:https://www.haomeiwen.com/subject/boyodttx.html