题 如何在Java中拆分字符串


我有一个字符串, "004-034556",我想分成两个字符串:

string1=004
string2=034556

这意味着第一个字符串将包含之前的字符 '-',第二个字符串将包含后面的字符 '-'。我还想检查字符串是否有 '-' 在里面。如果没有,我会抛出异常。我怎样才能做到这一点?


1280
2017-08-14 03:01


起源


现在提出同样的问题会导致大量的负面投票 - Bharat Mukkala
id而不是搜索google / stackoverflow而不是读取javadocs - Reece Markowsky


答案:


只需使用适当的方法: String#split()

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

请注意,这需要一个 正则表达式所以记得逃避 特殊字符 如有必要。

那里 是12个具有特殊含义的字符:反斜杠 \,插入符号 ^,美元符号 $,期间或点 .,垂直条或管道符号 |问号 ?,星号或星号 *,加号 +,左括号 (,右括号 ),以及开口方括号 [,开放的大括号 {,这些特殊字符通常被称为“元字符”。

所以,如果你想拆分,例如期/点 . 意思是 ”任何角色“在正则表达式中,使用其中之一 反斜线 \ 如此逃避个人的特殊性格 split("\\."),或使用 人物类 [] 表示像这样的文字字符 split("[.]"),或使用 Pattern#quote() 像这样逃避整个字符串 split(Pattern.quote("."))

String[] parts = string.split(Pattern.quote(".")); // Split on period.

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

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

注意,这不需要正则表达式。为此,使用 String#matches() 代替。

如果您想在结果部分中保留分割字符,请使用 积极的看法。如果您希望将拆分字符放在左侧,请通过前缀使用正向lookbehind ?<= 关于模式的小组。

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

2349
2017-08-14 03:05



为什么使用哈希符号来分隔String的方法? - Crowie
@Crowie:javadoc风格。 - BalusC
转角案例:如果找不到 reugalr expression 它返回一个包含整个字符串的元素数组。 - mklimek
Pattern.quote我在找什么:) - Dev911


直接处理字符串的替代方法是使用带捕获组的正则表达式。这样做的优点是可以直接表示对输入的更复杂的约束。例如,以下内容将字符串拆分为两部分,并确保两者都只包含数字:

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

68
2017-08-14 11:28



这是一个很好的解决方案,但第一部分应该是 m.group(1),第二部分 m.group(2)从那以后 m.group(0) 实际上返回完全匹配的模式。我想我也记得 group(0) 曾经是第一个匹配而不是完整模式,也许这在最近的Java版本更新中有所改变。 - ptstone
谢谢。看着 docs.oracle.com/javase/7/docs/api/java/util/regex/...,你是对的 - 与大多数其他正则表达式库一致,组0是完全匹配,并且捕获的组从1开始。正如你所说,我怀疑这可能已经改变,因为我最初写的答案,但在任何case我会更新它以反映当前的行为。 - Rob Hague


String[] result = yourString.split("-");
if (result.length != 2) 
     throw new IllegalArgumentException("String not in correct format");

这会将您的字符串分成两部分。数组中的第一个元素将是包含之前的东西的部分 -,数组中的第二个元素将包含字符串后面的部分 -

如果数组长度不是2,则字符串的格式不是: string-string

看看 split() 方法 String 类。

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-int-


39
2017-08-14 03:06



这将接受“-555”作为输入并返回[,555]。如果接受此要求是有效的,那么要求没有明确定义。我建议编写一些单元测试来定义所需的行为。 - Michael Konietzka
最安全的是将(result.length!= 2)更改为(result.length <2) - Uncle Iroh


// 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]);
}

26
2017-11-16 06:30



JavaDoc明确指出: “StringTokenizer 是一个遗留类,但出于兼容性原因而保留 在新代码中不鼓励使用它。建议任何寻求此功能的人都使用 split 的方法 String 或者 java.util.regex 而是包。“ - bvdb


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

应该做你想做的事。 String类有许多用string操作的方法。


23
2017-08-14 03:06





这些要求留有了解释空间。我建议写一个方法,

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] or [333-333,33] 还是错误?等等。


17
2017-08-14 06:57



有用的建议,但实际上并不是问题的答案。如果您支持另一个详细的答案,则首选评论。 - Chris Mountford


假如说

  • 你真的不需要正则表达式来进行拆分
  • 你碰巧已经在你的应用程序中使用了apache commons lang

最简单的方法是使用 StringUtils#split(java.lang.String,char)。如果你不需要正则表达式,这比开箱即用的Java更方便。就像它的手册所说,它的工作原理如下:

A null input String returns null.

 StringUtils.split(null, *)         = null
 StringUtils.split("", *)           = []
 StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
 StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
 StringUtils.split("a:b:c", '.')    = ["a:b:c"]
 StringUtils.split("a b c", ' ')    = ["a", "b", "c"]

我建议使用commong-lang,因为它通常包含很多可用的东西。但是,如果除了进行拆分之外你不需要它,那么实现自己或逃避正则表达式是一个更好的选择。


15
2018-03-25 06:43





使用 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

假设如果 - 在你的字符串中不存在,它返回给定的字符串,你不会得到任何异常。


15
2017-07-01 04:35





你也可以这样试试

 String concatenated_String="hi^Hello";

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

14
2018-01-15 09:58





使用Java 8:

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

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

14
2017-12-01 09:32



如果要删除空白添加 .map(String::trim) 之后 split - Roland