如何在Java中拆分字符串?

1917

我想要将字符串"004-034556"按照分隔符"-"拆分成两个字符串:

part1 = "004";
part2 = "034556";

这意味着第一个字符串将包含'-'之前的字符,而第二个字符串将包含'-'之后的字符。

我还想检查字符串中是否有'-'

39个回答

3368
使用名称恰当的方法 String#split()
String string = "004-034556";
String[] parts = string.split("-");
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556

请注意,split的参数被认为是一个正则表达式,所以如果需要,请记得转义特殊字符

12个具有特殊含义的字符:反斜杠\、脱字符^、美元符号$、句点或点号.、竖线或管道符号|、问号?、星号或乘号*、加号+、左括号(、右括号)、左方括号[、左花括号{。这些特殊字符通常称为“元字符”。

例如,要按句点.(在正则表达式中表示“任何字符”)拆分字符串,可以使用反斜杠\来转义单个特殊字符,如split("\\."),或使用字符类[]来表示字面字符,如split("[.]"),或使用Pattern#quote()来转义整个字符串,如split(Pattern.quote("."))
String[] parts = string.split(Pattern.quote(".")); // Split on the exact string.

如果要事先测试字符串是否包含某些字符,只需使用 String#contains()

if (string.contains("-")) {
    // Split it.
} else {
    throw new IllegalArgumentException("String " + string + " does not contain -");
}

注意,这不是使用正则表达式的方法。如果需要使用正则表达式,请使用String#matches()
如果您希望在结果中保留分割字符,则可以使用正向先行断言。如果您想让分割字符出现在左侧,请在模式前缀中添加?<=组来使用正向后行断言。
String string = "004-034556";
String[] parts = string.split("(?<=-)");
String part1 = parts[0]; // 004-
String part2 = parts[1]; // 034556

如果您希望分隔符位于右侧,请在模式前缀中使用正向预查,即在模式上加上?=

String string = "004-034556";
String[] parts = string.split("(?=-)");
String part1 = parts[0]; // 004
String part2 = parts[1]; // -034556

如果您想限制结果部分的数量,那么可以将所需数量作为split()方法的第二个参数提供。
String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42

35
为什么要使用井号符号来分隔字符串方法? - Crowie
104
@Crowie: Javadoc 风格。 - BalusC
11
特殊情况:如果找不到“正则表达式”,它将返回一个只包含整个字符串的单元素数组。 - klimat

89

一个替代直接处理字符串的方法是使用带有捕获组的正则表达式。这种方式的优点在于可以轻松地对输入应用更复杂的限制。例如,以下代码将字符串分为两部分,并确保两部分都仅由数字组成:

import java.util.regex.Pattern;
import java.util.regex.Matcher;

class SplitExample
{
    private static Pattern twopart = Pattern.compile("(\\d+)-(\\d+)");

    public static void checkString(String s)
    {
        Matcher m = twopart.matcher(s);
        if (m.matches()) {
            System.out.println(s + " matches; first part is " + m.group(1) +
                               ", second part is " + m.group(2) + ".");
        } else {
            System.out.println(s + " does not match.");
        }
    }

    public static void main(String[] args) {
        checkString("123-4567");
        checkString("foo-bar");
        checkString("123-");
        checkString("-4567");
        checkString("123-4567-890");
    }
}

在这种情况下,由于模式是固定的,可以事先编译并作为静态成员存储(在示例中,在类加载时初始化)。 正则表达式为:

(\d+)-(\d+)

括号表示捕获组; 匹配正则表达式的字符串可以通过Match.group()方法访问,如所示。 \d匹配单个十进制数字,+表示“匹配前面的表达式一次或多次”。-没有特殊含义,因此只匹配输入中的该字符。请注意,在将其编写为Java字符串时,需要双倍转义反斜杠。以下是一些其他示例:

([A-Z]+)-([A-Z]+)          // Each part consists of only capital letters 
([^-]+)-([^-]+)            // Each part consists of characters other than -
([A-Z]{2})-(\d+)           // The first part is exactly two capital letters,
                           // the second consists of digits

这是一个很好的解决方案,但是第一部分应该是 m.group(1) ,第二部分应该是 m.group(2) ,因为 m.group(0) 实际上返回完整的匹配模式。我记得 group(0) 也曾经是第一个匹配项而不是完整的模式,也许这在最近的 Java 版本更新中有所改变。 - ptstone

50

使用:

String[] result = yourString.split("-");
if (result.length != 2) 
     throw new IllegalArgumentException("String not in correct format");
这将把你的字符串分成两个部分。数组中的第一个元素将包含在-之前的内容,而数组中的第二个元素将包含在-之后的字符串部分。 如果数组长度不为2,则该字符串不符合格式:string-string。 请查看String类中的split()方法。

6
这将接受“-555”作为输入,并返回[,555]。如果可以接受这个值,要求并没有定义得很清楚。我建议编写一些单元测试来定义所需的行为。 - Michael Konietzka
1
最保险的做法是将 (result.length != 2) 改为 (result.length < 2)。 - Uncle Iroh

38

这个:

String[] out = string.split("-");

应该做你想要的事情。 string 类有许多方法可以操作字符串。


31
// This leaves the regexes issue out of question
// But we must remember that each character in the Delimiter String is treated
// like a single delimiter        

public static String[] SplitUsingTokenizer(String subject, String delimiters) {
   StringTokenizer strTkn = new StringTokenizer(subject, delimiters);
   ArrayList<String> arrLis = new ArrayList<String>(subject.length());

   while(strTkn.hasMoreTokens())
      arrLis.add(strTkn.nextToken());

   return arrLis.toArray(new String[0]);
}

64
JavaDoc 明确声明:StringTokenizer是一个保留下来以确保兼容性的遗留类,不建议在新代码中使用。建议寻求此功能的人使用 Stringsplit 方法或 java.util.regex 包。 - bvdb

27

使用Java 8:

    List<String> stringList = Pattern.compile("-")
            .splitAsStream("004-034556")
            .collect(Collectors.toList());

    stringList.forEach(s -> System.out.println(s));

2
如果您想要删除空格,请在 split 后添加 .map(String::trim) - Roland

21

使用org.apache.commons.lang.StringUtils的split方法,该方法可以根据您要拆分的字符或字符串来拆分字符串。

方法签名:

public static String[] split(String str, char separatorChar);

根据您的需求,您想要在字符串中找到“-”并将其拆分。

您可以按照以下方式进行简单操作:

String str = "004-034556";

String split[] = StringUtils.split(str,"-");

输出:

004
034556
假设您的字符串中不存在-,则返回给定的字符串,并且不会出现任何异常。

20

总结一下:在Java中至少有五种方法可以拆分字符串:

  1. String.split():

 String[] parts ="10,20".split(",");
  • Pattern.compile(regexp).splitAsStream(input):

  •  List<String> strings = Pattern.compile("\\|")
           .splitAsStream("010|020202")
           .collect(Collectors.toList());
    
  • StringTokenizer(遗留类):

     StringTokenizer strings = new StringTokenizer("Welcome to EXPLAINJAVA.COM!", ".");
     while(strings.hasMoreTokens()){
         String substring = strings.nextToken();
         System.out.println(substring);
     }
    
  • Google Guava Splitter:

     Iterable<String> result = Splitter.on(",").split("1,2,3,4");
    
  • Apache Commons StringUtils:

  •  String[] strings = StringUtils.split("1,2,3,4", ",");
    

    因此,您可以根据您的需求选择最佳选项,例如返回类型(数组、列表或可迭代对象)。

    这里提供了这些方法和最常见示例的大概述(如何按点、斜杠、问号等拆分)。


    19

    这些要求存在解释的空间。我建议编写一个方法,

    public final static String[] mySplit(final String s)
    

    你可以使用String.split(..)来实现,它会封装这个函数。当然,你也应该为输入字符串和期望结果编写一些单元测试,并验证其行为。

    良好的测试候选对象应包括:

     - "0022-3333"
     - "-"
     - "5555-"
     - "-333"
     - "3344-"
     - "--"
     - ""
     - "553535"
     - "333-333-33"
     - "222--222"
     - "222--"
     - "--4555"
    

    通过定义相应的测试结果,您可以指定行为。

    例如,如果"-333"应返回[, 333],或者它是一个错误。 是否可以将"333-333-33"分别分隔为[333,333-33][333-333,33],或者这是一个错误?等等。


    5
    有用的建议,但并非对问题的实际回答。如果您要支持另一个答案并提供详细说明,请使用评论。 - Chris Mountford
    请使用 split (String regex, int limit) 而不是 split (String regex)。有关参考,请访问 https://www.geeksforgeeks.org/split-string-java-examples/。 - Ryan Augustine

    17

    您也可以尝试像这样

     String concatenated_String="hi^Hello";
    
     String split_string_array[]=concatenated_String.split("\\^");
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接