我想通过分隔符“-”将字符串“004-034556”拆分为两个字符串:

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

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

我还想检查字符串中是否有“-”。


当前回答

请不要使用StringTokenizer类,因为它是出于兼容性原因而保留的遗留类,并且不鼓励在新代码中使用它。我们也可以使用其他人建议的拆分方法。

String[] sampleTokens = "004-034556".split("-");
System.out.println(Arrays.toString(sampleTokens));

正如预期的那样,它将打印:

[004, 034556]

在这个答案中,我还想指出Java8中拆分方法的一个变化。String#split()方法使用Pattern.split,现在它将删除结果数组开头的空字符串。请注意Java 8文档中的以下更改:

当输入开始时宽度匹配为正时序列,则在开头包含一个空前导子字符串生成的阵列。然而,开头的宽度为零永远不会产生这样的空前导子字符串。

对于以下示例,这意味着:

String[] sampleTokensAgain = "004".split("");
System.out.println(Arrays.toString(sampleTokensAgain));

我们将得到三个字符串:[0,0,4],而不是像Java7和以前的情况那样得到四个字符串。还要检查这个类似的问题。

其他回答

使用适当命名的方法String#split()。

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

请注意,split的参数假定为正则表达式,因此如果需要,请记住转义特殊字符。

有12个字符具有特殊含义:反斜杠\、插入符号^、美元符号$、句点或点。,竖条或管道符号|,问号?,星号或星号*、加号+、左括号(,右括号)和左方括号[,左大括号{,这些特殊字符通常被称为“元字符”。

例如,在句点/点上拆分。(这在正则表达式中表示“任何字符”),使用反斜杠\转义单个特殊字符,如so split(“\\.”),或使用字符类[]表示文字字符,如“[.]”,或使用Pattern#quote()转义整个字符串,如so split(“.”)。

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

如果要验证字母数字,请将正则表达式更改为[A-Za-z0-9]+-[A-Za-z 0-9]+

    public static final Pattern VALIDATE_PATTERN = Pattern.compile("[0-9]+-[0-9]+");

public static String[] validateString(String str) {
    if(VALIDATE_PATTERN.matcher(str).find()) {
        String[] output = str.split("-");
        if(output.length != 2) {
            throw new RuntimeException("Invalid string format");
        }
        return output;
    } else {
        throw new RuntimeException("Invalid string format");
    }
}
public class SplitTest {

    public static String[] split(String text, String delimiter) {
        java.util.List<String> parts = new java.util.ArrayList<String>();

        text += delimiter;

        for (int i = text.indexOf(delimiter), j=0; i != -1;) {
            String temp = text.substring(j,i);
            if(temp.trim().length() != 0) {
                parts.add(temp);
            }
            j = i + delimiter.length();
            i = text.indexOf(delimiter,j);
        }

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


    public static void main(String[] args) {
        String str = "004-034556";
        String delimiter = "-";
        String result[] = split(str, delimiter);
        for(String s:result)
            System.out.println(s);
    }
}

直接处理字符串的另一种方法是将正则表达式与捕获组一起使用。这样做的优点是,它可以直接暗示对输入的更复杂的约束。例如,以下命令将字符串拆分为两部分,并确保两者仅由数字组成:

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

消耗最少资源的最快方式可能是:

String s = "abc-def";
int p = s.indexOf('-');
if (p >= 0) {
    String left = s.substring(0, p);
    String right = s.substring(p + 1);
} else {
  // s does not contain '-'
}