JavaRush /Java 博客 /Random-ZH /Java中的Split方法:将字符串分成几部分

Java中的Split方法:将字符串分成几部分

已在 Random-ZH 群组中发布
让我们来谈谈字符串分割方法:它的作用以及为什么需要它。很容易猜到它是分割字符串的,但是它在实践中是如何工作的呢?让我们仔细看看该方法是如何工作的,并讨论一些不明显的细节,同时找出String类中实际上有多少个split方法。我们走吧!

Java String.split 的定义和签名

Java 中的split方法使用正则表达式指定的分隔符将字符串拆分为子字符串。让我们给出方法签名并开始我们的潜水:
String[] split(String regex)
从签名中可以清楚地看出两点:
  1. 该方法返回一个字符串数组。
  2. 该方法采用正则表达式字符串作为参数。
让我们根据上面给出的定义分别看看每件事。
  1. 该方法返回一个字符串数组。

    定义包含以下内容:“ Java 中的split方法将字符串拆分为子字符串。” 这些子字符串由该方法收集到一个数组中并表示其返回值。

  2. 该方法采用正则表达式字符串作为参数。

    再次记住定义:“使用正则表达式指定的分隔符将字符串拆分为子字符串。” 接受的regex参数是应用于源字符串并匹配源字符串中的分隔符(或字符组合)的正则表达式模式。

Java中的Split方法:将字符串分成几部分 - 1

实践中的分割

现在让我们言归正传吧。假设我们有一个包含单词的字符串。例如,像这样:
我爱Java
我们需要将字符串分解成单词。我们看到,在这一行中,单词之间用空格分隔。在这种情况下,空间是分隔符角色的理想选择。解决这个问题的代码如下所示:
public class Main {
    public static void main(String[] args) {
        String str = "I love Java";
        String[] words = str.split(" ");
        for (String word : words) {
            System.out.println(word);
        }
    }
}
main方法 的输出将是以下几行:
我爱Java
让我们看几个split方法如何工作的示例:
线 分隔符 该方法的结果
“我爱Java” “”(空格字符) { “我”“爱”“Java” }
“192.168.0.1:8080” “:” { “192.168.0.1”“8080” }
“红、橙、黄” “,” { “红色”“橙色”“黄色” }
“红、橙、黄” “,” { “红色”“橙色”“黄色” }
请注意上表中最后两行之间的差异。在倒数第二行中,分隔符是逗号,因此该行被分割成某些单词具有前导空格。在最后一行中,我们使用逗号和空格字符作为分隔符。因此,生成的数组不包含任何带前导空格的行。这只是一个小细节,表明仔细选择正确的分离器是多么重要。

前导分隔符

还有一个更重要的细微差别。如果源字符串以分隔符开头,则结果数组的第一个元素将为空字符串。在示例中,它看起来像这样: 源字符串:"I love Java" 分隔符:" " 结果数组: { "" , "I" , "love" , "Java" } 但是如果源字符串以分隔符结尾并且不开始,结果会不同: 源字符串:“I love Java” 分隔符:“” 结果数组:{ "I" , "love" , "Java" } 我们在代码中查看split方法的变体在源字符串的末尾和/或开头带有分隔符:
public class Main {
    public static void main(String[] args) {
        print("I love Java".split(" "));
        print(" I love Java".split(" "));
        print("I love Java ".split(" "));
        print(" I love Java ".split(" "));
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}
main方法 的输出将是这样的:
[我,爱,Java] [,我,爱,Java] [我,爱,Java] [,我,爱,Java]
再次注意,当源字符串中的第一个字符是分隔符时,生成的数组将以空字符串作为其第一个元素。

超载的家伙

String类还有另一个具有以下签名的 split方法:
String[] split(String regex, int limit)
此方法有一个额外的限制参数:它确定正则表达式模式应用于源字符串的次数。以下是解释:

限制 > 0

应用限制-1次。在这种情况下,数组的长度不会超过限制值。数组的最后一个元素将是找到的最后一个分隔符后面的字符串部分。例子:
public class Main {
    public static void main(String[] args) {
        print("I love Java".split(" ", 1));
        print("I love Java".split(" ", 2));
        /*
         Output:
         [I love Java]
         [I, love Java]
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}

限制 < 0

分隔符搜索模式会尽可能多次地应用于字符串。结果数组的长度可以是任意的。例子:
public class Main {
    public static void main(String[] args) {
        // Notice the space at the end of the line
        print("I love Java ".split(" ", -1));
        print("I love Java ".split(" ", -2));
        print("I love Java ".split(" ", -12));
        /*
         Output:
        [I, love, Java, ]
        [I, love, Java, ]
        [I, love, Java, ]

        Note that the last element of the array is
        an empty string, resulting from the space
        at the end of the original string.
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}

限制 0

limit < 0 一样,分隔符模式会尽可能多次地应用于字符串。结果数组可以是任意长度。如果最后一个元素等于空字符串,它们将在最终数组中被丢弃。例子:
public class Main {
    public static void main(String[] args) {
        // Notice the space at the end of the line
        print("I love Java ".split(" ", 0));
        print("I love Java ".split(" ", 0));
        print("I love Java ".split(" ", 0));
        /*
         Output:
        [I, love, Java]
        [I, love, Java]
        [I, love, Java]
        Note the absence of empty strings at the end of the arrays
        */
    }

    static void print(String[] arr) {
        System.out.println(Arrays.toString(arr));
    }
}
如果我们查看带有一个参数的split方法 的实现,我们会发现该方法使用第二个参数为零来调用其重载的同级方法:
public String[] split(String regex) {
    return split(regex, 0);
}

各种例子

在工作实践中,有时会出现按照一定规则编制的线路。该行可以从任何地方“进入”我们的程序:
  • 来自第三方服务;
  • 来自对我们服务器的请求;
  • 来自配置文件;
  • ETC。
通常在这种情况下,程序员知道“游戏规则”。假设程序员知道他拥有有关用户的信息,这些信息是根据以下模式存储的:
用户 ID|用户登录名|用户电子邮件
例如,我们取具体值:
135|bender|bender@gmail.com
现在程序员面临的任务是:编写一个向用户发送电子邮件的方法。他可以使用以上述格式记录的有关用户的信息。那么,我们将继续分析的子任务是将电子邮件地址与用户的一般信息隔离开来。这是split方法有用的一个示例。毕竟,如果我们查看模板,我们就会明白,为了从所有信息中提取用户的电子邮件地址,我们只需要使用 split 方法来分割该。然后电子邮件地址将位于结果数组的最后一个元素中。让我们举一个此类方法的示例,该方法采用包含用户信息的字符串并返回用户的电子邮件。为了简单起见,我们假设该字符串始终与我们需要的格式匹配:
public class Main {
    public static void main(String[] args) {
        String userInfo = "135|bender|bender@gmail.com";
        System.out.println(getUserEmail(userInfo));
        // Output: bender@gmail.com
    }

    static String getUserEmail(String userInfo) {
        String[] data = userInfo.split("\\|");
        return data[2]; // or data[data.length - 1]
    }
}
注意分隔符:“\\|” 。因为在正则表达式中“|” - 这是一个与某些逻辑相关的特殊字符;为了将其用作常规字符(我们想要在源字符串中找到的字符),我们需要使用两个反斜杠转义该字符。让我们看另一个例子。假设我们有一个订单的信息,其格式大致如下:
商品编号_1,商品名称_1,商品价格_1;商品编号_2,商品名称_2,商品价格_2;...;商品编号_n,商品名称_n,商品价格_n
或者让我们取具体值:
1、黄瓜,20.05;2、西红柿,123.45;3、野兔,0.50
我们面临着计算订单总成本的任务。这里我们将不得不多次使用split方法。第一步是通过“;”符号将字符串拆分为其组成部分。然后,在每个这样的部分中,我们将获得有关单个产品的信息,以便我们将来进行处理。然后,在每个产品中,我们将使用“,”符号分隔信息,并从结果数组中取出具有特定索引的元素(其中存储价格),将其转换为数字形式并编译最终成本的订单。让我们编写一个方法来计算所有这些:
public class Main {
    public static void main(String[] args) {
        String orderInfo = "1, cucumbers, 20.05; 2, tomatoes, 123.45; 3, hares, 0.50";
        System.out.println(getTotalOrderAmount(orderInfo));
        // Output: 144.0
    }

    static double getTotalOrderAmount(String orderInfo) {
        double totalAmount = 0d;
        final String[] items = orderInfo.split(";");

        for (String item : items) {
            final String[] itemInfo = item.split(",");
            totalAmount += Double.parseDouble(itemInfo[2]);
        }

        return totalAmount;
    }
}
尝试自己弄清楚这个方法是如何工作的。基于这些例子,我们可以说,当我们有一些字符串形式的信息,我们需要从中提取一些更具体的信息时,就会使用 split方法。

结果

我们查看了String类的split方法。需要使用特殊的分隔符将字符串拆分为其组成部分。该方法返回一个字符串数组(字符串的组成部分)。接受与分隔符匹配的正则表达式。我们研究了这种方法的各种微妙之处:
  • 前导分隔符;
  • 有两个参数的超载兄弟。
我们还尝试模拟一些“现实生活”的情况,使用split方法来解决虽然虚构但非常现实的问题。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION