如何在Java中拆分字符串

riy*_*ana 1564 java string

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

string1="004";
string2="034556";
Run Code Online (Sandbox Code Playgroud)

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

Bal*_*usC 2788

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

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

请注意,这需要使用正则表达式,因此请记住在必要时转义特殊字符.

12个特殊含义的字符:反斜杠\,插入符号^,美元符号$,句点或点.,垂直条或管道符号|,问号?,星号或星号*,加号+,左括号(,右括号),以及开口方括号[,开口花括号{,这些特殊字符通常称为"元字符".

所以,如果你想拆就如周期/点.,这意味着" 任何字符 "的正则表达式,使用反斜线\逃避个别特殊字符,像这样split("\\."),或使用字符类[]来表示文字字符(S)像这样split("[.]"),或者使用Pattern#quote()以像这样逃避整个字符串split(Pattern.quote(".")).

String[] parts = string.split(Pattern.quote(".")); // Split on period.
Run Code Online (Sandbox Code Playgroud)

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

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

注意,这不需要正则表达式.为此,请String#matches()改用.

如果您想在结果部分中保留分割字符,请使用正面外观.如果您希望拆分字符最终位于左侧,请通过?<=在模式上添加前缀组来使用正向lookbehind .

String string = "004-034556";
String[] parts = string.split("(?<=-)");
String part1 = parts[0]; // 004-
String part2 = parts[1]; // 034556
Run Code Online (Sandbox Code Playgroud)

如果您希望将拆分字符放在右侧,请通过?=在模式上添加前缀组来使用正向前瞻.

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

如果您想限制结果零件的数量,那么您可以提供所需的数字作为split()方法的第二个参数.

String string = "004-034556-42";
String[] parts = string.split("-", 2);
String part1 = parts[0]; // 004
String part2 = parts[1]; // 034556-42
Run Code Online (Sandbox Code Playgroud)

  • @Crowie:javadoc风格. (92认同)
  • 为什么使用哈希符号来分隔String的方法? (25认同)
  • 转角情况:如果找不到`reugalr expression`,则返回一个带整个字符串的元素数组. (8认同)
  • @David:1)问题中没有涉及到这一点。2)它不会抛出异常。3)OP询问如何拆分,而不是如何进行子串。4)休息一下,深呼吸,把你脑子里的所有负面情绪都扔掉:) (6认同)
  • 不能相信投票最多的版本是这样的。1)如果原始字符串包含两个“-”,则part2不是发布者想要的。2)没有问题中提到的错误处理。3)低效率。单个字符搜索需要正则表达式构造和匹配。创建了额外的数组,等等。 (2认同)

Rob*_*gue 74

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

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

由于模式在此实例中是固定的,因此可以预先编译并存储为静态成员(在示例中的类加载时初始化).正则表达式是:

(\d+)-(\d+)
Run Code Online (Sandbox Code Playgroud)

括号表示捕获组; 匹配该正则表达式部分的字符串可以通过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
Run Code Online (Sandbox Code Playgroud)


jjn*_*guy 41

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

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

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

查看课堂上的split()方法String.

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

  • 这将接受"-555"作为输入并返回[,555].如果接受此要求是有效的,那么要求没有明确定义.我建议编写一些单元测试来定义所需的行为. (5认同)

sec*_*ask 28

String[] out = string.split("-");
Run Code Online (Sandbox Code Playgroud)

应该做你想要的事情.String类有很多用string操作的方法.


Mny*_*kka 28

// 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]);
}
Run Code Online (Sandbox Code Playgroud)

  • JavaDoc明确指出:*"`StringTokenizer`是一个遗留类,出于兼容性原因而保留,尽管**在新代码中不鼓励**.建议任何寻求此功能的人都使用`String的`split`方法`或者`java.util.regex`包."* (59认同)

Som*_*era 20

使用Java 8:

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

    stringList.forEach(s -> System.out.println(s));
Run Code Online (Sandbox Code Playgroud)

  • 如果要删除空格,请在`split`之后添加`.map(String :: trim)` (2认同)

Mic*_*zka 19

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

public final static String[] mySplit(final String s)
Run Code Online (Sandbox Code Playgroud)

它封装了这个功能.当然,您可以使用其他答案中提到的String.split(..)来实现.

您应该为输入字符串和所需的结果和行为编写一些单元测试.

优秀考生应包括:

 - "0022-3333"
 - "-"
 - "5555-"
 - "-333"
 - "3344-"
 - "--"
 - ""
 - "553535"
 - "333-333-33"
 - "222--222"
 - "222--"
 - "--4555"
Run Code Online (Sandbox Code Playgroud)

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

例如,if "-333"应该返回[,333]或者是否是错误.可以"333-333-33"分开[333,333-33] or [333-333,33]或者是错误吗?等等.

  • 有用的建议,但实际上并不是问题的答案.如果您支持另一个详细的答案,则首选评论. (3认同)

eis*_*eis 16

假如说

  • 你真的不需要正则表达式来进行拆分
  • 你碰巧已经在你的应用程序中使用了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"]
Run Code Online (Sandbox Code Playgroud)

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


SHU*_*RAN 15

你也可以这样试试

 String concatenated_String="hi^Hello";

 String split_string_array[]=concatenated_String.split("\\^");
Run Code Online (Sandbox Code Playgroud)


小智 15

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

方法签名:

public static String[] split(String str, char separatorChar);
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您希望在存在" - "时拆分字符串.

您可以简单地执行以下操作:

String str = "004-034556";

String split[] = StringUtils.split(str,"-");
Run Code Online (Sandbox Code Playgroud)

输出:

004
034556
Run Code Online (Sandbox Code Playgroud)

假设如果-字符串中不存在,则返回给定的字符串,并且不会出现任何异常.


Vit*_*nko 13

对于简单的用例,String.split()应该完成这项工作.如果你使用guava,还有一个Splitter类,它允许链接不同的字符串操作并支持CharMatcher:

Splitter.on('-')
       .trimResults()
       .omitEmptyStrings()
       .split(string);
Run Code Online (Sandbox Code Playgroud)


Rav*_*abu 13

字符串使用Regex分割多个字符

public class StringSplitTest {
     public static void main(String args[]) {
        String s = " ;String; String; String; String, String; String;;String;String; String; String; ;String;String;String;String";
        //String[] strs = s.split("[,\\s\\;]");
        String[] strs = s.split("[,\\;]");
        System.out.println("Substrings length:"+strs.length);
        for (int i=0; i < strs.length; i++) {
            System.out.println("Str["+i+"]:"+strs[i]);
        }
     }
  }
Run Code Online (Sandbox Code Playgroud)

输出:

Substrings length:17
Str[0]:
Str[1]:String
Str[2]: String
Str[3]: String
Str[4]: String
Str[5]: String
Str[6]: String
Str[7]:
Str[8]:String
Str[9]:String
Str[10]: String
Str[11]: String
Str[12]:
Str[13]:String
Str[14]:String
Str[15]:String
Str[16]:String
Run Code Online (Sandbox Code Playgroud)

但是不要指望所有JDK版本都有相同的输出.我看到一些JDK版本中存在一个错误,其中第一个空字符串被忽略.最新的JDK版本中不存在此错误,但在JDK 1.7后期版本和1.8早期版本之间存在某些版本.


小智 12

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

  1. String.split():

    String[] parts ="10,20".split(",");
    
    Run Code Online (Sandbox Code Playgroud)
  2. Pattern.compile(正则表达式).splitAsStream(输入):

    List<String> strings = Pattern.compile("\\|")
          .splitAsStream("010|020202")
          .collect(Collectors.toList());
    
    Run Code Online (Sandbox Code Playgroud)
  3. StringTokenizer(遗留类):

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

    Iterable<String> result = Splitter.on(",").split("1,2,3,4");
    
    Run Code Online (Sandbox Code Playgroud)
  5. Apache Commons StringUtils:

    String[] strings = StringUtils.split("1,2,3,4", ",");
    
    Run Code Online (Sandbox Code Playgroud)

因此,您可以根据需要为您选择最佳选项,例如返回类型(数组,列表或可迭代).

以下是这些方法和最常见示例的大概述(如何按点,斜线,问号等分割)


Dav*_*vid 11

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

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 '-'
}
Run Code Online (Sandbox Code Playgroud)

  • 最稀缺的资源通常是程序员的时间和注意力.此代码比备用代码消耗更多的资源. (6认同)

Akh*_*bey 10

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Raj*_*mar 9

您可以使用以下语句通过换行符拆分字符串:

String textStr[] = yourString.split("\\r?\\n");
Run Code Online (Sandbox Code Playgroud)

您可以使用以下语句通过连字符/字符拆分字符串:

String textStr[] = yourString.split("-");
Run Code Online (Sandbox Code Playgroud)


小智 9

import java.io.*;

public class BreakString {

  public static void main(String args[]) {

    String string = "004-034556-1234-2341";
    String[] parts = string.split("-");

    for(int i=0;i<parts.length;i++) ?
      System.out.println(parts[i]);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我可以分享建议,你的答案如何带来比已经接受的解决方案更多的价值?http://stackoverflow.com/a/3481842/420096在这种情况下,您可以对现有解决方案进行投票,特别是如果这是一个明显无关紧要的案例. (4认同)

Sar*_*dra 8

你可以使用Split():

import java.io.*;

public class Splitting
{

    public static void main(String args[])
    {
        String Str = new String("004-034556");
        String[] SplittoArray = Str.split("-");
        String string1 = SplittoArray[0];
        String string2 = SplittoArray[1];
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,您可以使用StringTokenizer:

import java.util.*;
public class Splitting
{
    public static void main(String[] args)
    {
        StringTokenizer Str = new StringTokenizer("004-034556");
        String string1 = Str.nextToken("-");
        String string2 = Str.nextToken("-");
    }
}
Run Code Online (Sandbox Code Playgroud)


Kes*_*ath 7

一种方法是在for-each循环中运行String并使用所需的拆分字符.

public class StringSplitTest {

    public static void main(String[] arg){
        String str = "004-034556";
        String split[] = str.split("-");
        System.out.println("The split parts of the String are");
        for(String s:split)
        System.out.println(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

The split parts of the String are:
004
034556
Run Code Online (Sandbox Code Playgroud)


i_a*_*ero 7

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

String[] sampleTokens = "004-034556".split("-");
System.out.println(Arrays.toString(sampleTokens));
Run Code Online (Sandbox Code Playgroud)

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

[004, 034556]
Run Code Online (Sandbox Code Playgroud)

在这个答案中,我还想指出Java 8中的方法发生split一个变化.的字符串#分裂()方法利用了Pattern.split,现在将在结果阵列的开始删除空字符串.请注意Java 8文档中的此更改:

当在输入序列的开头存在正宽度匹配时,在结果数组的开头包括空的前导子串.然而,开头的零宽度匹配从不会产生这样的空前导子串.

这意味着以下示例:

String[] sampleTokensAgain = "004".split("");
System.out.println(Arrays.toString(sampleTokensAgain));
Run Code Online (Sandbox Code Playgroud)

我们将获得三个字符串:[0, 0, 4]而不是Java 7及之前的四个字符串.还要检查这个类似的问题.


Aks*_*wad 7

以下两种方式实现它.

方法1:由于你必须用特殊字符分割两个数字,你可以使用正则表达式

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

public class TrialClass
{
    public static void main(String[] args)
    {
        Pattern p = Pattern.compile("[0-9]+");
        Matcher m = p.matcher("004-034556");

        while(m.find())
        {
            System.out.println(m.group());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

方式2:使用字符串拆分方法

public class TrialClass
{
    public static void main(String[] args)
    {
        String temp = "004-034556";
        String [] arrString = temp.split("-");
        for(String splitString:arrString)
        {
            System.out.println(splitString);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Roh*_*dey 6

无论是否存在任何类型的分隔符,您都可以使用StringTokenizer将字符串拆分为两个或多个部分:

StringTokenizer st = new StringTokenizer("004-034556", "-");
while(st.hasMoreTokens())
{
    System.out.println(st.nextToken());
}
Run Code Online (Sandbox Code Playgroud)


rgh*_*ome 5

您只需要考虑两种方法。

将String.split用于一个字符分隔符,或者您不关心性能

如果性能不是问题,或者分隔符是不是正则表达式特殊字符的单个字符(即,不是之一.$|()[{^?*+\),则可以使用String.split

String[] results = input.split(",");
Run Code Online (Sandbox Code Playgroud)

如果分隔符是单个字符而不在上面的列表中,则split方法进行了优化以避免使用正则表达式。否则,它必须编译一个正则表达式,这是不理想的。

如果使用复杂的定界符并且您关心性能,请使用Pattern.split并预编译模式。

如果性能是一个问题,并且分隔符不是上述之一,则应预编译正则表达式模式,然后可以重复使用。

// Save this somewhere
Pattern pattern = Pattern.compile("[,;:]");

/// ... later
String[] results = pattern.split(input);
Run Code Online (Sandbox Code Playgroud)

最后一个选项仍会创建一个新Matcher对象。您也可以缓存该对象并为每个输入重置它,以实现最佳性能,但这会更加复杂并且不是线程安全的。