Dividi Java String per New Line


390

Sto cercando di dividere il testo in un JTextAreautilizzo di una regex per dividere la stringa da \nTuttavia, questo non funziona e ho anche provato da \r\n|\r|ne molte altre combinazioni di regex. Codice:

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
qual è l'errore che ricevi? Non dire "non funziona", ciò non significa nulla. Comunicaci l'errore / risultato che ottieni. Questo è il primo passo nel debug del codice: capire qual è il risultato sbagliato e come il vostro programma è arrivato a questo.
Chii,

Cosa vuoi davvero fare? - le linee di interruzione quando vengono immesse in JTextArea? - scoprire dove sta facendo il JTextArea avvolgimenti di linea? - ???
user85421

Risposte:


732

Questo dovrebbe coprirti:

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

Ci sono solo due newline (UNIX e Windows) di cui devi preoccuparti.


43
Un documento JTextArea DOVREBBE usare solo '\ n'; le sue viste ignorano completamente "\ r". Ma se stai cercando più di un tipo di separatore, potresti anche cercare tutti e tre: "\ r? \ N | \ r".
Alan Moore,

10
Mac 9 utilizza \ r. OSX 10 utilizza \ n
Raekye

$ {fn: length (fn: split (data, '\\ r? \\ n'))} non funziona in jstl

4
@antak sì, splitper impostazione predefinita rimuove le stringhe vuote finali se vengono fornite il risultato della divisione. Per disattivare questo meccanismo è necessario utilizzare la versione sovraccaricata di split(regex, limit)con limite negativo come text.split("\\r?\\n", -1). Altre informazioni: Split String Java rimosso valori vuoti
Pshemo

1
Il commento di @stivlo è disinformazione ed è un peccato che abbia così tanti voti positivi. Come ha sottolineato @ Raekye, OS X (ora noto come macOS) ha usato \ n come separatore di linea da quando è stato rilasciato nel 2001. Mac OS 9 è stato rilasciato nel 1999 e non ho mai visto un Mac OS 9 o una macchina inferiore in produzione. Non esiste un singolo sistema operativo moderno che utilizza \ r come separatore di riga. Non scrivere MAI codice che prevede di essere il separatore di linea su Mac, a meno che a) non ti occupi del retro computing, b) abbia una macchina con sistema operativo 9 attivata ec) possa determinare in modo affidabile che la macchina è effettivamente sistema operativo 9.
James McLaughlin,

133

String#split​(String regex)il metodo utilizza regex (espressioni regolari). Poiché Java 8 regex supporta \Rche rappresenta (dalla documentazione della classe Pattern ):

Matcher di interruzioni di riga
\ R Qualsiasi sequenza di interruzioni di riga Unicode è equivalente a \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Quindi possiamo usarlo per abbinare:

Come vedete, \r\nviene posizionato all'inizio di regex, il che assicura che regex proverà ad abbinare prima questa coppia , e solo se quella corrispondenza fallisce, proverà ad abbinare i separatori di riga di singoli caratteri .


Quindi, se si desidera dividere il separatore in linea, utilizzare split("\\R").

Se non si desidera rimuovere dall'array risultante che segue stringhe vuote,"" utilizzare split(regex, limit)con limitparametri negativi come split("\\R", -1).

Se si desidera trattare una o più righe vuote continue come uso delimitatore singolo split("\\R+").


4
Sì, è la risposta migliore. Peccato che la domanda sia stata posta sei anni troppo presto per questa risposta.
Dawood ibn Kareem,

Ho finito per dividere \\R+, per evitare qualsiasi personaggio di fine linea che non fosse coperto da \\Rsolo.
SeverityOne

128

Se non vuoi linee vuote:

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

4
le doppie barre rovesciate non sono necessarie, vedere la sezione "Barre rovesciate, escape
angryITguy,


1
Questo ha funzionato su Mac OSX quando la risposta sopra non ha funzionato.
Giovanni

Questo ha funzionato anche per me. Soluzione eccellente Ha funzionato per i seguenti 2 casi: 1) mi sono svegliato alle 3 in punto. \ R \ n \ r \ nSpero 2) questa è la vita reale \ r \ nso I
logixplayer

2
@tresf Non è possibile utilizzare quantificatori tra parentesi quadre.
CX gamer l'

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

Questo dovrebbe essere indipendente dal sistema


42
È un'idea interessante, ma dovresti fare attenzione che il testo utilizzi effettivamente il separatore di riga del sistema. Ho un sacco di molti file di testo in Unix (ad esempio XML) che utilizza separatori "Windows" e parecchi in Windows che utilizzano separatori Unix.
Maarten Bodewes,

Funziona anche su Android
ruX

7
I file creati in un sistema operativo Windows e trasferiti in un sistema operativo Unix conterranno comunque \ r \ n separatori. Penso che sia meglio giocare in sicurezza e prendere in considerazione entrambi i separatori.
bvdb,

17
Questo è un approccio molto problematico! Il file potrebbe non provenire dal sistema che esegue il codice. Scoraggio vivamente questo tipo di progetti "indipendenti dal sistema" che in realtà dipendono da un sistema specifico, il sistema di runtime.
Martin,

4
@Shervin Non è mai il modo migliore per farlo. In realtà è una pessima pratica. Considera qualche altro programmatore che chiama System.setProperty ("line.separator", "non hai alcun punto"); Il tuo codice è rotto. Potrebbe anche essere chiamato in modo simile da una dipendenza di cui non si ha conoscenza.
Martin,

14

Un nuovo metodo linesè stato introdotto per Stringclassificare, che ritorna Stream<String>

Restituisce un flusso di sottostringhe estratte da questa stringa partizionata dai terminatori di linea.

I terminatori di linea riconosciuti sono avanzamento riga "\ n" (U + 000A), ritorno a capo "\ r" (U + 000D) e un ritorno a capo seguito immediatamente da un avanzamento riga "\ r \ n" (U + 000D U + 000A ).

Ecco alcuni esempi:

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 # linee ()


12

Non è necessario duplicare i caratteri di escape nei gruppi di personaggi.

Per tutte le linee non vuote usare:

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

Si. Se hanno bisogno di una doppia fuga ovunque, ne hanno bisogno ovunque. Lo spazio bianco fuoriesce come \re \npuò avere una o due barre rovesciate; funzionano in entrambi i modi.
Alan Moore,

2
La doppia barra rovesciata '\\'nel codice diventa un '\'carattere e viene quindi passata al motore RegEx, quindi il "[\\r\\n]"codice diventa [\r\n]in memoria e RegEx lo elaborerà. Non so come esattamente Java gestisca RegEx, ma è buona norma passare un modello di stringa ASCII "puro" al motore RegEx e lasciarlo elaborare anziché passare caratteri binari. "[\r\n]"diventa (hex) 0D0Ain memoria e un motore RegEx potrebbe accettarlo mentre un altro si strozzerà. Quindi la linea di fondo è che anche se il sapore Java di RegEx non ne ha bisogno, mantieni la doppia
barra

10

Nella JDK11la Stringclasse ha un lines()metodo:

Restituisce un flusso di linee estratte da questa stringa, separate da terminatori di linea.

Inoltre, la documentazione prosegue dicendo:

Un terminatore di riga è uno dei seguenti: un carattere di avanzamento riga "\ n" (U + 000A), un carattere di ritorno a capo "\ r" (U + 000D) o un ritorno a capo seguito immediatamente da un avanzamento di riga "\ r \ n "(U + 000D U + 000A). Una riga è una sequenza di zero o più caratteri seguita da un terminatore di riga oppure è una sequenza di uno o più caratteri seguita dalla fine della stringa. Una linea non include il terminatore di linea.

Con questo si può semplicemente fare:

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

quindi se vuoi un array:

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

Dato che questo metodo restituisce uno Stream su molte opzioni in quanto consente di scrivere espressioni concise e dichiarative di operazioni forse parallele.


7

Forse questo avrebbe funzionato:

Rimuovere le doppie barre rovesciate dal parametro del metodo split:

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

8
Non proprio. Quando si scrive un regex sotto forma di un valore letterale String Java, è possibile utilizzare "\ n" per passare al compilatore regex un simbolo di avanzamento riga o "\\ n" per passargli la sequenza di escape per un avanzamento riga. Lo stesso vale per tutte le altre escape di spazi bianchi tranne \ v, che non è supportato nei letterali Java.
Alan Moore,

3
@Yuval. Mi dispiace che non sia corretto, non ti serve affatto " Backslash
escape

7

Tutte le risposte fornite qui in realtà non rispettano la definizione di Javas di nuove righe come fornita ad esempio in BufferedReader # readline. Java è accettare \n, \re \r\ncome la nuova linea. Alcune delle risposte corrispondono a più righe vuote o file non validi. Per esempio. <sometext>\n\r\n<someothertext>quando si utilizza [\r\n]+si tradurrebbe in due righe.

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

Al contrario, la risposta sopra ha le seguenti proprietà:

  • è conforme alla definizione Javas di una nuova linea come ad es. BufferedReader lo sta utilizzando
  • non corrisponde a più nuove righe
  • non rimuove le righe vuote finali

6

Se, per qualche motivo, non si desidera utilizzare String.split(ad esempio, a causa di espressioni regolari ) e si desidera utilizzare la programmazione funzionale su Java 8 o versioni successive:

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

So che questa potrebbe essere una soluzione eccessiva.
Danilo Piazzalunga,

3
O String[] lines = new BufferedReader(...).lines().toArray(String[]::new);per un array anziché un elenco. La cosa bella di questa soluzione è che BufferedReaderconosce tutti i tipi di terminatori simili, quindi può gestire il testo in tutti i tipi di formati. (La maggior parte delle soluzioni basate su regex pubblicate qui non sono
Ted Hopp

2
Questa soluzione è obsoleta a partire da Java 11 e dall'introduzione del metodo String.lines ().
leventov,

4

Per preservare le righe vuote dall'uso schiacciato:

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

3

Il codice sopra non fa effettivamente nulla di visibile - solo calcualtes quindi scarica il calcolo. È il codice che hai usato o solo un esempio per questa domanda?

prova a fare textAreaDoc.insertString (int, String, AttributeSet) alla fine?


insertUpdate () è un metodo DocumentListener. Supponendo che l'OP lo stia utilizzando correttamente, il tentativo di modificare il documento all'interno del metodo listener genererà un'eccezione. Ma hai ragione: il codice in quella domanda in realtà non fa nulla.
Alan Moore,

2

In alternativa alle risposte precedenti, l' SplitterAPI di guava può essere utilizzata se altre operazioni devono essere applicate alle linee risultanti, come tagliare le linee o filtrare le linee vuote:

import com.google.common.base.Splitter;

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

Si noti che il risultato è Iterableun array e non un array.


1

String lines[] =String.split( System.lineSeparator())


1

Dopo tentativi falliti sulla base di tutte le soluzioni fornite. Sostituisco \ncon qualche parola speciale e poi divido. Per me seguire ha fatto il trucco:

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

Non ho potuto replicare l'esempio fornito nella domanda. Ma immagino che questa logica possa essere applicata.


1

Le risposte di cui sopra non mi hanno aiutato su Android, grazie alla risposta Pshemo che ha funzionato per me su Android. Lascerò alcune delle risposte di Pshemo qui:

split("\\\\n")

0
  • prova questa speranza che ti sia stata utile

 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

Esistono tre diverse convenzioni (si potrebbe dire che quelle sono di fatto standard) per impostare e visualizzare un'interruzione di linea:

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

In alcuni editor di testo, è possibile scambiare uno con l'altro:

Notepad ++

La cosa più semplice è normalizzare line feede quindi dividere.

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

0

C'è un nuovo ragazzo in città, quindi non è necessario affrontare tutte le complessità di cui sopra. Da JDK 11 in poi , devi solo scrivere come singola riga di codice, dividerà le righe e ti restituirà Stream di 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
}}

Alcuni riferimenti https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#lines () https://www.azul.com/90-new -Caratteristiche-e-API-in-jdk-11 /

Spero che questo possa essere utile a qualcuno. Buona codifica.


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

}

Ciò impallidisce rispetto alle altre risposte, che sono più esplicative e meno pesanti. Potresti spiegare cosa stai realizzando con questo codice e perché fornirebbe una risposta adeguata?
Makoto,

2
Ciò non ha nulla a che fare con la suddivisione di un file in righe. Valuta di rimuovere la tua risposta.
Martin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.