web-dev-qa-db-ja.com

Javaで区切り文字を削除せずに、いくつかの区切り文字で文字列を分割するにはどうすればよいですか?

Stringの分割で問題に直面しています。

Stringをいくつかの区切り文字で分割したいが、その区切り文字は失わない。

Javaでsomestring.split(String separator)メソッドを使用すると、Stringは分割されますが、Stringからセパレータ部分は削除されます。発生する。

以下のような結果が必要です:

String string1="Ram-sita-laxman";
String seperator="-";
string1.split(seperator);

出力:

[Ram, sita, laxman]

しかし、代わりに次のような結果が必要です:

[Ram, -sita, -laxman]

このような出力を取得する方法はありますか?

65
sag
string1.split("(?=-)");

これは、splitが実際に 正規表現 を取るために機能します。実際に見ているのは、「ゼロ幅の正の先読み」です。

もっと説明したいのですが、娘はお茶会をしたいです。 :)

編集:戻る!

これを説明するために、最初に別のsplit操作を示します。

"Ram-sita-laxman".split("");

これにより、長さゼロのすべての文字列で文字列が分割されます。すべての文字の間にゼロ長の文字列があります。したがって、結果は次のようになります。

["", "R", "a", "m", "-", "s", "i", "t", "a", "-", "l", "a", "x", "m", "a", "n"]

次に、正規表現("")長さゼロの文字列のみに一致する場合後にダッシュが続く場合

"Ram-sita-laxman".split("(?=-)");
["Ram", "-sita", "-laxman"]

その例では、?=は「先読み」を意味します。より具体的には、「positive lookahead」を意味します。なぜ「ポジティブ」なのですか? negative lookahead(?!)これは、notにダッシュが続くすべての長さゼロの文字列で分割されます。

"Ram-sita-laxman".split("(?!-)");
["", "R", "a", "m-", "s", "i", "t", "a-", "l", "a", "x", "m", "a", "n"]

ポジティブルックビハインド?<=)ダッシュが前にある長さゼロの文字列ごとに分割されます。

"Ram-sita-laxman".split("(?<=-)");
["Ram-", "sita-", "laxman"]

最後に、負の後読み?<!)ダッシュが前に付いたnotであるすべての長さゼロの文字列で分割します:

"Ram-sita-laxman".split("(?<!-)");
["", "R", "a", "m", "-s", "i", "t", "a", "-l", "a", "x", "m", "a", "n"]

これら4つの式は、集合的にlookaround式として知られています。

ボーナス:それらをまとめる

twoのLookaround式を組み合わせた最近出会った例を示したかっただけです。 CapitalCase識別子をトークンに分割したいとします:

"MyAwesomeClass" => ["My", "Awesome", "Class"]

次の正規表現を使用してこれを実現できます。

"MyAwesomeClass".split("(?<=[a-z])(?=[A-Z])");

これは、小文字((?<=[a-z]))と大文字((?=[A-Z]))。

この手法は、camelCase識別子でも機能します。

203
Adam Paynter

少し危険ですが、replace関数を使用してダミーのセパレータを導入できます。 Javaメソッドはわかりませんが、C#では次のようになります。

string1.Replace("-", "#-").Split("#");

もちろん、文字列の他の場所にないことが保証されているダミーの区切り文字を選択する必要があります。

4
Andrew Cooper

これを行う方法は、文字列を分割し、最初の文字列を除く抽出された各文字列の先頭にセパレータを追加することです。

2
Dalmas
seperator="-";
String[] splitstrings = string1.split(seperator);
for(int i=1; i<splitstring.length;i++)
{
   splitstring[i] = seperator + splitstring[i];
}

それがLadaRaiderの答えに合ったコードです。

1
mad

アダムは頭に釘を打ちました!私は彼の答えを使用して、ファイルダイアログブラウザからリッチテキストボックスにファイル名テキストを挿入する方法を見つけました。私が遭遇した問題は、ファイル文字列の「\」に新しい行を追加していたときでした。 string.splitコマンドは\で分割され、削除されました。 Adamのコードを混合して使用した後、ファイル名の各\の後に新しい行を作成できました。

私が使用したコードは次のとおりです。

OpenFileDialog fd = new OpenFileDialog();
        fd.Multiselect = true;
        fd.ShowDialog();

        foreach (string filename in fd.FileNames)
        {
            string currentfiles = uxFiles.Text;
            string value = "\r\n" + filename;

     //This line allows the Regex command to split after each \ in the filename. 

            string[] lines = Regex.Split(value, @"(?<=\\)");

            foreach (string line in lines)
            {
                uxFiles.Text = uxFiles.Text + line + "\r\n";
            }
        }

楽しい!

セイウチ

0
Walrusking