Javaで文字列を分割する方法


1640

私は、文字列を持っている"004-034556"私は2つの文字列に分割したいこと:

string1="004";
string2="034556";

つまり、最初の文字列にはの前の'-'文字が含まれ、2番目の文字列にはの文字が含まれます'-'。文字列が含ま'-'れているかどうかも確認したいと思います。そうでない場合は、例外をスローします。これどうやってするの?

回答:


2935

適切な方法を使用してください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()代わりしてください。

結果のパーツの分割文字を保持したい場合は、ポジティブルックアラウンドを利用してください。分割文字を左端にしたい場合?<=は、パターンの前にグループを付けることにより、肯定的な後読みを使用します。

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()メソッドの2番目の引数として必要な数を指定できます。

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

27
なぜハッシュシンボルを使用してStringのメソッドを区切るのですか?
Crowie 2013

94
@Crowie:javadocスタイル。
BalusC 2013

9
コーナーケース:見つからない場合reugalr expressionは、文字列全体を含む1つの要素配列を返します。
klimat

2
最も投票されたバージョンがこのようなものであるとは信じられません。1)元の文字列に2つの「-」が含まれている場合、part2は投稿者が求めているものではありません。2)質問で述べられているように、エラー処理は行われません。3)低効率。単一文字の検索には、正規表現の構築とマッチングが必要です。追加のアレイの作成など
David

1
@David:1)それは質問には含まれていません。2)例外をスローしません。3)OPは、分割する方法ではなく、分割する方法を尋ねます。4)休憩を取り、深く呼吸し、頭の中のすべてのネガティブさを
捨てる

79

文字列を直接処理する代わりに、キャプチャグループで正規表現を使用することもできます。これには、入力に対してより高度な制約を課すことが簡単になるという利点があります。たとえば、次は文字列を2つの部分に分割し、両方が数字のみで構成されていることを確認します。

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は1桁の10進数に一致し、+は「前の式の1つ以上に一致する」を意味します。-は特別な意味を持たないため、入力内のその文字に一致します。円記号は二重にエスケープする必要があることに注意してください。これを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)2番目の部分になるはずです。完全なパターンではなく、最初の一致であったことも覚えていると思います。これは、最近のJavaバージョンの更新で変更された可能性があります。m.group(2)m.group(0)group(0)
ptstone 2017

1
ありがとう。docs.oracle.com/javase/7/docs/api/java/util/regex/…を見ると、そうです。他のほとんどの正規表現ライブラリと同様に、グループ0は完全一致であり、キャプチャされたグループは1.おっしゃるとおり、私は最初に回答を書いてから変更されたのではないかと思いますが、いずれにしても、現在の動作を反映するように更新します。
ロブ・ハーグ

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

これにより、文字列が2つの部分に分割されます。配列の最初の要素はの前の-要素を含む部分であり、配列の2番目の要素はの後の文字列の部分を含みます-

配列の長さが2でない場合、文字列は次の形式ではありません:string-string

クラスのsplit()メソッドを確認してくださいString

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


5
これは「-555」を入力として受け入れ、[、555]を返します。これを受け入れることが有効である場合、要件は明確に定義されていません。望ましい動作を定義するためにいくつかの単体テストを書くことをお勧めします。
マイケル・コニエツカ2010

(result.length!= 2)を(result.length <2)に変更するのが最も安全
イロおじさん

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

あなたがしたいことをする必要があります。文字列クラスには、文字列を操作する多くのメソッドがあります。


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

60
JavaDocには、新しいコードでは使用を推奨されていませんStringTokenizer互換性のために保持されているレガシークラスです。この機能を求める人は、splitメソッドStringまたはjava.util.regexパッケージを代わりに使用することをお勧めします。」
bvdb

23

Java 8の場合:

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

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

2
空白を削除したい場合は、次の.map(String::trim)後に追加しますsplit
Roland

18

要件は解釈の余地を残しました。メソッドを書くことをお勧めします

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

この関数をカプセル化します。もちろん、実装の他の回答で述べたように、String.split(..)を使用できます。

入力文字列と目的の結果と動作のユニットテストをいくつか記述する必要があります。

優れたテストの候補者には次のものが含まれます。

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

対応するテスト結果を定義することで、動作を指定できます。

たとえば、if "-333"が返される[,333]か、それがエラーであるかなどです。"333-333-33"で分離でき[333,333-33] or [333-333,33]ますか、それともエラーですか?等々。


4
有用なアドバイスですが、実際には質問に対する回答ではありません。別の回答を詳細にサポートしている場合は、コメントが推奨されます。
クリスマウントフォード2014


16

あなたもこのように試すことができます

 String concatenated_String="hi^Hello";

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

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"]

commong-langを使用することをお勧めします。通常、これには使用可能な多くのものが含まれています。ただし、分割を行う以外に必要がない場合は、自分で実装するか、正規表現をエスケープすることをお勧めします。


15

分割する文字または文字列に基づいて文字列を分割できるorg.apache.commons.lang.StringUtilsの分割メソッドを使用します。

メソッドの署名:

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

あなたの場合、 "-"があるときに文字列を分割したいとします。

あなたは単に次のようにすることができます:

String str = "004-034556";

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

出力:

004
034556

-文字列にが存在しない場合は、指定された文字列を返し、例外は発生しないと仮定します。


14

要約すると、Javaで文字列を分割するには少なくとも5つの方法があります。

  1. String.split():

    String[] parts ="10,20".split(",");
  2. Pattern.compile(regexp).splitAsStream(入力):

    List<String> strings = Pattern.compile("\\|")
          .splitAsStream("010|020202")
          .collect(Collectors.toList());
  3. StringTokenizer(レガシークラス):

    StringTokenizer strings = new StringTokenizer("Welcome to EXPLAINJAVA.COM!", ".");
    while(strings.hasMoreTokens()){
        String substring = strings.nextToken();
        System.out.println(substring);
    }
  4. Googleグアバスプリッター:

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

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

したがって、必要に応じて最適なオプションを選択できます。たとえば、戻り値の型(配列、リスト、反復可能)などです。

ここでは、これらの方法の大概要と、最も一般的な例は、(など、ドット、スラッシュ、疑問符、によって分割する方法)であります


13

リソースを最も消費しない最速の方法は次のとおりです。

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 '-'
}

6
最も希少なリソースは、多くの場合、プログラマーの時間と注意です。このコードは、代替手段よりもそのリソースを多く消費します。
クリスマウントフォード2014

使用できる組み込みリソースがたくさんあり、実際に考慮されているパフォーマンスの場合、このソリューションにはパフォーマンス実行時間が不足しています
J Sanchez

1
エラーチェックを使用して単一の文字で単純な分割を行うには、これは正規表現バージョンと同じくらい複雑ではありません。
tekHedd

ブラボー!最後に、正規表現を使用しないこの質問への回答!この単純なタスクに正規表現を使用することは、むしろ頭のスクラッチャーです。この地球にはまだ正気なプログラマがいるのを見るのは良いことです:-)
ガブリエルマガナ

「-」は1つしかなく、例外が必要であり、結果はstring1とstring2に送られます。string1 = s.substring(0, s.indexOf("-")); string2 = s.substring(s.indexOf("-") + 1);それから作ってください。StringIndexOutOfBoundsException「-」がない場合は、自動的に取得されます。
カプラン

13

正規表現を使用した複数の文字による文字列分割

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

出力:

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

ただし、すべてのJDKバージョンで同じ出力を期待しないでください。最初のnull文字列が無視される一部のJDKバージョンに存在するバグ1つ見ました。このバグは最新のJDKバージョンには存在しませんが、JDK 1.7の最新バージョンと1.8の初期バージョンの間の一部のバージョンに存在します。



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

9

次のステートメントを使用すると、改行によって文字列を分割できます。

String textStr[] = yourString.split("\\r?\\n");

次のステートメントを使用して、ハイフン/文字で文字列を分割できます。

String textStr[] = yourString.split("-");

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

4
私がアドバイスを共有する可能性がある場合、あなたの答えはすでに受け入れられているソリューションよりどのように価値をもたらしますか?stackoverflow.com/a/3481842/420096そのような状況では、特にこれがそのような明らかな些細なケースである場合は特に、既存のソリューションに投票できます。
Sombriks、2016年

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

それ以外の場合は、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("-");
    }
}

8

本当に検討する必要のある方法は2つだけです。

1文字の区切り文字としてString.splitを使用するか、パフォーマンスを気にしない

パフォーマンスに問題がない場合、または区切り文字が正規表現の特殊文字ではない単一の文字(つまり、の1つではない.$|()[{^?*+\)である場合は、を使用できますString.split

String[] results = input.split(",");

区切り文字が上記のリストにない単一の文字である場合、splitメソッドには正規表現を使用しないように最適化されています。それ以外の場合は、正規表現をコンパイルする必要があり、これは理想的ではありません。

複雑な区切り文字を使用し、パフォーマンスを重視する場合は、Pattern.splitを使用してパターンをプリコンパイルします。

パフォーマンスが問題で、区切り文字が上記のいずれでもない場合は、再利用できる正規表現パターンをプリコンパイルする必要があります。

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

/// ... later
String[] results = pattern.split(input);

この最後のオプションでは、まだ新しいMatcherオブジェクトが作成されます。このオブジェクトをキャッシュして、最大のパフォーマンスを得るために入力ごとにリセットすることもできますが、これはやや複雑でスレッドセーフではありません。


7

これを行う1つの方法は、for-eachループで文字列を実行し、必要な分割文字を使用することです。

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

出力:

The split parts of the String are:
004
034556

7

StringTokenizerクラスは互換性のために保持されているレガシークラスであり、新しいコードでは使用しないようにしてください。また、他の人から提案された分割方法を利用することもできます。

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

そして、期待通りに印刷されます:

[004, 034556]

この回答ではsplit、Java 8のメソッドに対して行われた1つの変更についても指摘したいと思います。文字列#分割()メソッドは、を利用してPattern.split、今では結果の配列の開始時に空の文字列を削除します。Java 8のドキュメントにおけるこの変更に注意してください

入力シーケンスの先頭に正の幅の一致がある場合、結果の配列の先頭に空の先行部分文字列が含まれます。ただし、最初に幅が一致しないと、そのような空の先行部分文字列は生成されません。

これは、次の例の意味です。

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

3つの文字列を取得します。Java7 [0, 0, 4]以前の場合のように4つではありません。この同様の質問も確認してください。


7

ここでは、2つの方法でそれを実現します。

方法1:特殊文字で2つの数値を分割する必要があるため、正規表現を使用できます

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());
        }
    }
}

方法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);
        }
    }
}

6

StringTokenizerを使用すると、区切り文字のタイプに関係なく、文字列を2つ以上の部分に分割できます。

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

4

javadoc split()Stringクラスのメソッドを確認してください。

https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String)

String data = "004-034556-1212-232-232";
int cnt = 1;
for (String item : data.split("-")) {
        System.out.println("string "+cnt+" = "+item);
        cnt++;
}

ここに分割文字列の多くの例がありますが、コードを少し最適化しました。


に置き換え-|、何が起こるかを確認してください:)
R Sun

その場合は、stackoverflow.com
R Sun

4
String str="004-034556"
String[] sTemp=str.split("-");// '-' is a delimiter

string1=004 // sTemp[0];
string2=034556//sTemp[1];

3

Javaの組み込み関数を使用する代わりに、アルゴリズムを作成したかっただけです。

public static List<String> split(String str, char c){
    List<String> list = new ArrayList<>();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < str.length(); i++){
        if(str.charAt(i) != c){
            sb.append(str.charAt(i));
        }
        else{
            if(sb.length() > 0){
                list.add(sb.toString());
                sb = new StringBuilder();
            }
        }
    }

    if(sb.length() >0){
        list.add(sb.toString());
    }
    return list;
}

1

あなたは方法を使うことができますsplit

public class Demo {
    public static void main(String args[]) {
        String str = "004-034556";

        if ((str.contains("-"))) {
            String[] temp = str.split("-");
            for (String part:temp) {
                System.out.println(part);
            }
        }
        else {
            System.out.println(str + " does not contain \"-\".");
        }
    }
}

1

文字列を分割するには、String.split(regex)を使用します。次の例を確認してください。

String data = "004-034556";
String[] output = data.split("-");
System.out.println(output[0]);
System.out.println(output[1]);

出力

004
034556

注意:

この分割(正規表現)は、引数として正規表現を取ります。ピリオド/ドットなどの正規表現の特殊文字をエスケープすることを忘れないでください。


0
String s="004-034556";
for(int i=0;i<s.length();i++)
{
    if(s.charAt(i)=='-')
    {
        System.out.println(s.substring(0,i));
        System.out.println(s.substring(i+1));
    }
}

誰もが言及しているように、split()はあなたのケースで使用できる最良のオプションです。別の方法として、substring()を使用することができます。


0

文字列を分割するには、次を使用しますString.split(regex)

String phone = "004-034556";
String[] output = phone.split("-");
System.out.println(output[0]);
System.out.println(output[1]);

出力:

004
034556
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.