Java文字列を改行で分割


389

JTextArea正規表現を使用して文字列を分割することでテキストを分割しようとしていますが\n、これは機能せず、\r\n|\r|n他の多くの正規表現の組み合わせでも試しました。コード:

public void insertUpdate(DocumentEvent e) {
    String split[], docStr = null;
    Document textAreaDoc = (Document)e.getDocument();

    try {
        docStr = textAreaDoc.getText(textAreaDoc.getStartPosition().getOffset(), textAreaDoc.getEndPosition().getOffset());
    } catch (BadLocationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    split = docStr.split("\\n");
}

7
あなたが得るエラーは何ですか?「機能しない」とは言わないでください。それは何も意味しません。発生したエラー/結果をお知らせください。これがコードのデバッグの最初のステップです。間違った結果が何であるか、およびプログラムがそれをどのように行ったかを理解してください。
Chii

あなたは本当に何をしたいですか?-JTextAreaに入力された行を改行しますか?-JTextAreaが行の折り返しを行っている場所を見つけますか?-???
user85421 2009

回答:


732

これはあなたをカバーするはずです:

String lines[] = string.split("\\r?\\n");

心配する必要がある改行は本当に2つ(UNIXとWindows)だけです。


43
JTextAreaドキュメントは '\ n'のみを使用する必要があります(SHOULD)。そのビューは「\ r」を完全に無視します。ただし、複数の種類のセパレータを探す場合は、「\ r?\ n | \ r」の3つすべてを探すこともできます。
アランムーア

10
Mac 9は\ rを使用します。OSX 10は\ nを使用します
Raekye 2013年

$ {fn:length(fn:split(data、 '\\ r?\\ n'))}がjstlで機能しない

4
@antakはい、split分割の結果が使用された場合、デフォルトで後続の空の文字列を削除します。このメカニズムをオフにするにはsplit(regex, limit)、のような負の制限を持つのオーバーロードバージョンを使用する必要がありますtext.split("\\r?\\n", -1)。詳細:Java文字列分割により空の値が削除された
Pshemo

1
@stivloのコメントは誤った情報であり、非常に多くの賛成票があるのは残念です。@ Raekyeが指摘したように、OS X(現在はmacOSとして知られています)は、2001年にリリースされて以来、\ n行区切り文字として使用していました。MacOS 9は1999年にリリースされました。MacOS 9以下のマシンが使用されるのを見たことがありません。生産中。\ rを行区切り文字として使用する単一の最新のオペレーティングシステムはありません。Macで\ rが行区切り文字であることを期待するコードを記述しないでください。ただし、a)レトロコンピューティングを使用している場合、b)OS 9マシンを起動している場合、c)マシンが実際にOS 9であると確実に判断できる場合
ジェームズマクラフリン

132

String#split​(String regex)メソッドは正規表現(正規表現)を使用しています。Java 8の正規表現は、次\Rを表すものをサポートしているため(Patternクラスのドキュメントから):


改行マッチャー \ R任意のUnicode改行シーケンス。 \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

そのため、これを使用して一致させることができます。

ご覧のとおり\r\n、はregexの先頭に配置されます。これにより、regexが最初にこのペアとの一致を試み、その一致が失敗した場合にのみ、1文字の行区切り文字との一致を試みます。


したがって、行区切り文字で分割する場合はを使用しますsplit("\\R")

結果の配列の末尾の空の文字列を削除したくない""場合はsplit(regex, limit)、などの負のlimitパラメータを使用しますsplit("\\R", -1)

1つ以上の継続する空行を単一の区切り文字として扱う場合は、を使用しますsplit("\\R+")


4
はい、それが最良の答えです。残念ながら、この回答に対して6年も早く質問された。
Dawood ibnカリーム

一人で\\R+カバーされなかった行末文字を避けるために、私はで分割することになりまし\\Rた。
SeverityOne

128

空の行が必要ない場合:

String.split("[\\r\\n]+")

4
二重のバックスラッシュは不要です。「バックスラッシュ、エスケープ、引用」セクションを参照してください。docs.oracle.com
javase/


1
これはMac OSXでは機能しましたが、上記の回答では機能しませんでした。
ジョン

これも私にとってはうまくいきました。優れたソリューション。次の2つのケースで機能しました。1)3時に目が覚めました。\ r \ n \ r \ n2)これが現実の生活であることを願っています\ r \ n私
logixplayer

2
@tresf角かっこで数量詞を使用することはできません。
CXゲーマー

49
String.split(System.getProperty("line.separator"));

これはシステムに依存しないはずです


41
面白いアイデアですが、テキストが実際にシステムの行区切り文字を使用するように注意する必要があります。「Windows」セパレーターを使用するunix(例:XML)の下の多くのテキストファイルと、UNIXセパレーターを使用するかなりの数のWindowsのテキストファイルがあります。
Maarten Bodewes 2012

androidでも機能します
ruX

6
Windows OSで作成され、Unix OSに転送されたファイルには、\ r \ nセパレータがまだ含まれています。安全にプレーし、両方のセパレーターを考慮に入れる方が良いと思います。
bvdb 14

17
これは非常に問題の多いアプローチです!ファイルは、コードを実行しているシステムに由来していない可能性があります。特定のシステム、つまりランタイムシステムに実際に依存している、このような「システムに依存しない」設計はお勧めしません。
Martin

4
@Shervinそれを行うための最良の方法は決してありません。それは実際には非常に悪い習慣です。System.setProperty( "line.separator"、 "あなたには意味がありません");を呼び出す他のプログラマーを考えてみましょう。コードが壊れています。知らない依存関係からも同様に呼び出される可能性があります。
Martin

14

新しいメソッドlinesStringクラスに導入されました、戻ります Stream<String>

行末記号で区切られたこの文字列から抽出された部分文字列のストリームを返します。

認識されるラインターミネータは、ラインフィード "\ n"(U + 000A)、キャリッジリターン "\ r"(U + 000D)、キャリッジリターンの直後にラインフィード "\ r \ n"(U + 000D U + 000A)があります。 )。

以下にいくつかの例を示します。

jshell> "lorem \n ipusm \n sit".lines().forEach(System.out::println)
lorem
 ipusm
 sit

jshell> "lorem \n ipusm \r  sit".lines().forEach(System.out::println)
lorem
 ipusm
  sit

jshell> "lorem \n ipusm \r\n  sit".lines().forEach(System.out::println)
lorem
 ipusm
  sit

String#lines()


12

文字グループのエスケープ文字を2倍にする必要はありません。

空でないすべての行を使用します。

String.split("[\r\n]+")

そうです。どこでもダブルエスケープが必要な場合、どこでもそれが必要です。空白は、1つまたは2つのバックスラッシュ\rと同様に\nエスケープします。どちらの方法でも機能します。
アランムーア

2
'\\'コード内の二重のバックスラッシュは'\'文字になり、次にRegExエンジンに渡されるため"[\\r\\n]"、コード[\r\n]内ではメモリになり、RegExがそれを処理します。JavaがRegExを正確に処理する方法はわかりませんが、「純粋な」ASCII文字列パターンをRegExエンジンに渡し、バイナリ文字を渡すのではなく処理させることをお勧めします。メモリ内で"[\r\n]"(16進数)0D0Aになり、1つのRegExエンジンがそれを受け入れ、別のエンジンが窒息する可能性があります。つまり、JavaのRegExフレーバーでは必要ない場合でも、互換性のためにスラッシュを2つ続けてください
nurchi

10

では、クラスがあるメソッドを:JDK11Stringlines()

この文字列から抽出された行のストリームを、行末記号で区切って返します。

さらに、ドキュメンテーションは続けて言っています:

ラインターミネータは次のいずれかです。ラインフィード文字「\ n」(U + 000A)、キャリッジリターン文字「\ r」(U + 000D)、またはキャリッジリターンの直後にラインフィード「\ r」 \ n "(U + 000D U + 000A)。行は、0個以上の文字のシーケンスとそれに続く行終端記号、または1つ以上の文字のシーケンスとそれに続く文字列の終わりのいずれかです。行には行末記号は含まれません。

これで簡単にできます:

Stream<String> stream = str.lines();

次に、配列が必要な場合:

String[] array = str.lines().toArray(String[]::new);

このメソッドを指定すると、並列処理の可能性がある簡潔で宣言的式を記述できるようになるため、多くのオプションを使用してStream itを返します。


7

多分これはうまくいくでしょう:

splitメソッドのパラメーターから二重のバックスラッシュを削除します。

split = docStr.split("\n");

8
あんまり。Java文字列リテラルの形式で正規表現を記述する場合、「\ n」を使用して正規表現コンパイラに改行記号を渡すか、「\\ n」を使用して改行のエスケープシーケンスを渡すことができます。Javaリテラルではサポートされていない\ vを除いて、他のすべての空白エスケープでも同じことが言えます。
アランムーア

3
@ユヴァル。不正解です。不正解です。「バックスラッシュ、エスケープ、引用」は必要ありません。docs.oracle.com
javase /

7

ここで与えられたすべての答えは実際には、例えばBufferedReader#readlineで与えられたJavaの新しい行の定義を尊重しません。Javaは受け入れて\n\rそして\r\n新しい行として。一部の回答は、複数の空の行または不正な形式のファイルと一致します。例えば。<sometext>\n\r\n<someothertext>使用[\r\n]+すると2行になります。

String lines[] = string.split("(\r\n|\r|\n)", -1);

対照的に、上記の答えには次の特性があります。

  • それは例えばBufferedReaderがそれを使用しているような新しい行のJava定義に準拠しています
  • 複数の改行に一致しない
  • 末尾の空行は削除されません

6

何らかの理由でString.split(たとえば、正規表現のために)使用したくなく、Java 8以降で関数型プログラミングを使用したい場合:

List<String> lines = new BufferedReader(new StringReader(string))
        .lines()
        .collect(Collectors.toList());

これはやり過ぎの解決策になる可能性があることを知っています。
Danilo Piazzalunga

3
またはString[] lines = new BufferedReader(...).lines().toArray(String[]::new);、リストではなく配列の場合。このソリューションの良いところは、BufferedReaderあらゆる種類のターミネーターを認識しているため、あらゆる形式のテキストを処理できることです。(ここに掲載されている正規表現ベースのソリューションのほとんどは、この点で不十分です。)
Ted Hopp

2
このソリューションは、Java 11とString.lines()メソッドの導入により廃止されました。
leventov 2018年

4

押しつぶされて使用されないように空の行を保持するには:

String lines[] = String.split("\\r?\\n", -1);

3

上記のコードは実際に目に見えることは何もしません-計算してから計算をダンプするだけです。あなたが使ったコードですか、それともこの質問の例ですか?

最後にtextAreaDoc.insertString(int、String、AttributeSet)を実行してみますか?


insertUpdate()はDocumentListenerメソッドです。OPが正しく使用していると仮定すると、リスナーメソッド内からドキュメントを変更しようとすると、例外が生成されます。しかし、その通りです。その質問のコードは実際には何もしません。
アランムーア

2

前の回答の代わりに、Splitter行のトリミングや空行のフィルタリングなど、他の操作を結果の行に適用する場合は、guavaのAPIを使用できます。

import com.google.common.base.Splitter;

Iterable<String> split = Splitter.onPattern("\r?\n").trimResults().omitEmptyStrings().split(docStr);

結果はIterable配列であり、配列ではないことに注意してください。



1

与えられたすべてのソリューションに基づいて試行が失敗した後。\n特別な単語に置き換えて分割します。私にとっては、次のトリックを行いました:

article = "Alice phoned\n bob.";
article = article.replace("\\n", " NEWLINE ");
String sen [] = article.split(" NEWLINE ");

質問の例を再現できませんでした。しかし、このロジックは適用できると思います。



0
  • この希望を試してみてください

 String split[], docStr = null;
Document textAreaDoc = (Document)e.getDocument();

try {
    docStr = textAreaDoc.getText(textAreaDoc.getStartPosition().getOffset(), textAreaDoc.getEndPosition().getOffset());
} catch (BadLocationException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

split = docStr.split("\n");

0

改行を設定して表示するには、3つの異なる規則があります(これらは事実上の標準であると言えます)。

  • carriage return + line feed
  • line feed
  • carriage return

一部のテキストエディターでは、一方を他方と交換することができます。

メモ帳++

最も簡単なのは、正規化しline feedてから分割することです。

final String[] lines = contents.replace("\r\n", "\n")
                               .replace("\r", "\n")
                               .split("\n", -1);

0

町に新しい男の子がいるので、上記のすべての複雑さに対処する必要はありません。 JDK 11以降では、コードを1行で記述するだけで、行が分割され、Stream of Stringが返されます。

public class MyClass {
public static void main(String args[]) {
   Stream<String> lines="foo \n bar \n baz".lines();
   //Do whatever you want to do with lines
}}

いくつかの参考文献。 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#lines() https://www.azul.com/90-new -features-and-apis-in-jdk-11 /

これが誰かのお役に立てば幸いです。ハッピーコーディング。


-1
package in.javadomain;

public class JavaSplit {

    public static void main(String[] args) {
        String input = "chennai\nvellore\ncoimbatore\nbangalore\narcot";
        System.out.println("Before split:\n");
        System.out.println(input);

        String[] inputSplitNewLine = input.split("\\n");
        System.out.println("\n After split:\n");
        for(int i=0; i<inputSplitNewLine.length; i++){
            System.out.println(inputSplitNewLine[i]);
        }
    }

}

これは、他の回答と比較すると見劣りします。他の回答は、より説明的でコードの負荷が低くなります。このコードで何を達成しているのか、そしてなぜそれが適切な答えを出すのかを説明できますか?
マコト

2
これは、ファイルを行に分割することとは関係ありません。答えを削除することを検討してください。
Martin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.