Split Java String par New Line

390

J'essaie de diviser le texte en JTextAreautilisant une expression régulière pour diviser la chaîne par \nCependant, cela ne fonctionne pas et j'ai également essayé par \r\n|\r|net de nombreuses autres combinaisons d'expressions régulières. Code:

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");
}
dr.manhattan
la source
7
quelle est l'erreur que vous obtenez? Ne dites pas "ne fonctionne pas", cela ne veut rien dire. Dites-nous l'erreur / résultat que vous obtenez. C'est la première étape du débogage du code - déterminez quel est le mauvais résultat et comment votre programme y est parvenu.
Chii
Que voulez-vous vraiment faire? - les lignes de rupture au fur et à mesure de leur entrée dans JTextArea? - trouver où JTextArea fait des sauts de ligne? - ???
user85421

Réponses:

732

Cela devrait vous couvrir:

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

Il n'y a vraiment que deux nouvelles lignes (UNIX et Windows) dont vous devez vous soucier.

cletus
la source
43
Un document JTextArea DEVRAIT utiliser uniquement '\ n'; ses vues ignorent complètement '\ r'. Mais si vous cherchez plus d'un type de séparateur, vous pouvez aussi bien chercher les trois: "\ r? \ N | \ r".
Alan Moore
10
Mac 9 utilise \ r. OSX 10 utilise \ n
Raekye
$ {fn: length (fn: split (data, '\\ r? \\ n'))} ne fonctionne pas dans jstl
4
@antak yes, splitpar défaut, supprime les chaînes vides de fin si elles résultent d'un fractionnement. Pour désactiver ce mécanisme, vous devez utiliser une version surchargée de split(regex, limit)avec une limite négative comme text.split("\\r?\\n", -1). Plus d'informations: Java String Split a supprimé les valeurs vides
Pshemo
1
Le commentaire de @stivlo est une désinformation, et il est regrettable qu'il ait autant de votes positifs. Comme l'a souligné @ Raekye, OS X (maintenant connu sous le nom de macOS) utilise \ n comme séparateur de ligne depuis sa sortie en 2001. Mac OS 9 est sorti en 1999, et je n'ai jamais vu de machine Mac OS 9 ou inférieure utilisée en production. Il n'y a pas un seul système d'exploitation moderne qui utilise \ r comme séparateur de ligne. N'écrivez JAMAIS de code qui s'attend à ce que \ r soit le séparateur de lignes sur Mac, sauf si a) vous êtes dans le rétro-informatique, b) faites tourner une machine OS 9 et c) pouvez déterminer de manière fiable que la machine est réellement OS 9.
James McLaughlin
133

String#split​(String regex)utilise regex (expressions régulières). Depuis Java 8 regex prend en charge \Rqui représente (à partir de la documentation de la classe Pattern ):

Correspondance de saut de ligne
\ R Toute séquence de saut de ligne Unicode est équivalente à \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Nous pouvons donc l'utiliser pour faire correspondre:

Comme vous le voyez, il \r\nest placé au début de l'expression régulière, ce qui garantit que l'expression régulière tentera de faire correspondre cette paire en premier, et seulement si cette correspondance échoue, elle essaiera de faire correspondre les séparateurs de ligne à caractère unique .


Donc, si vous voulez diviser l'utilisation du séparateur de ligne split("\\R").

Si vous ne souhaitez pas supprimer du tableau résultant les chaînes vides de fin,"" utilisez-les split(regex, limit)avec un limitparamètre négatif comme split("\\R", -1).

Si vous souhaitez traiter une ou plusieurs lignes vides continues comme un seul délimiteur split("\\R+").

Pshemo
la source
4
Oui, c'est la meilleure réponse. Dommage que la question ait été posée six ans trop tôt pour cette réponse.
Dawood ibn Kareem
J'ai fini par me séparer \\R+, pour éviter tout caractère de fin de ligne qui n'était pas couvert par \\Rseul.
SeverityOne
128

Si vous ne voulez pas de lignes vides:

String.split("[\\r\\n]+")
Gombo
la source
4
les doubles barres obliques inverses ne sont pas nécessaires, voir la section " Barres
angryITguy
1
Cela a fonctionné sur Mac OSX lorsque la réponse ci-dessus n'a pas fonctionné.
John
Cela a également fonctionné pour moi. Excellente solution. Cela a fonctionné pour les 2 cas suivants: 1) je me suis réveillé à 3 heures. \ R \ n \ r \ nJ'espère 2) c'est la vraie vie \ r \ nso I
logixplayer
2
@tresf Vous ne pouvez pas utiliser de quantificateurs entre crochets.
CX gamer
49
String.split(System.getProperty("line.separator"));

Cela devrait être indépendant du système

Shervin Asgari
la source
42
C'est une idée intéressante, mais vous devez vous assurer que le texte utilise réellement le séparateur de ligne du système. J'ai beaucoup de nombreux fichiers texte sous Unix (par exemple XML) qui utilisent des séparateurs "Windows" et un bon nombre sous Windows qui utilisent des séparateurs Unix.
Maarten Bodewes
Fonctionne même sur Android
ruX
7
Les fichiers créés dans un système d'exploitation Windows et transférés vers un système d'exploitation Unix contiendront toujours des séparateurs \ r \ n. Je pense qu'il vaut mieux jouer prudemment et tenir compte des deux séparateurs.
bvdb
17
C'est une approche très problématique! Le fichier peut ne pas provenir du système exécutant le code. Je déconseille fortement ces types de conceptions "indépendantes du système" qui dépendent en fait d'un système spécifique, le système d'exécution.
Martin
4
@Shervin Ce n'est jamais la meilleure façon de le faire. C'est en fait une très mauvaise pratique. Considérez un autre programmeur appelant System.setProperty ("line.separator", "vous n'avez aucun point"); Votre code est cassé. Il peut même être appelé de manière similaire par une dépendance dont vous n'avez aucune connaissance.
Martin
14

Une nouvelle méthode linesa été introduite en Stringclasse dans, qui renvoie Stream<String>

Renvoie un flux de sous-chaînes extraites de cette chaîne partitionnée par des terminateurs de ligne.

Les terminateurs de ligne reconnus sont le saut de ligne "\ n" (U + 000A), le retour chariot "\ r" (U + 000D) et un retour chariot suivi immédiatement d'un saut de ligne "\ r \ n" (U + 000D U + 000A ).

Voici quelques exemples:

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

Chaîne # lignes ()

Anton Balaniuc
la source
12

Vous n'avez pas à doubler les caractères d'échappement dans les groupes de caractères.

Pour toutes les lignes non vides, utilisez:

String.split("[\r\n]+")
Martin
la source
Oui. S'ils ont besoin d'une double fuite n'importe où, ils en ont besoin partout. Les espaces s'échappent comme \ret \npeuvent avoir une ou deux barres obliques inverses; ils fonctionnent de toute façon.
Alan Moore
2
La double barre oblique inverse '\\'dans le code devient un '\'caractère et est ensuite transmise au moteur RegEx, donc "[\\r\\n]"dans le code devient [\r\n]en mémoire et RegEx traitera cela. Je ne sais pas exactement comment Java gère RegEx, mais c'est une bonne pratique de passer un modèle de chaîne ASCII "pur" au moteur RegEx et de le laisser traiter plutôt que de passer des caractères binaires. "[\r\n]"devient (hex) 0D0Aen mémoire et un moteur RegEx pourrait l'accepter tandis qu'un autre s'étoufferait. Donc, en fin de compte, même si la version Java de RegEx n'en a pas besoin, gardez les doubles barres obliques pour la compatibilité
nurchi
10

Dans JDK11la Stringclasse a une lines()méthode:

Renvoyer un flux de lignes extraites de cette chaîne, séparées par des terminateurs de ligne.

De plus, la documentation poursuit en disant:

Un terminateur de ligne est l'un des éléments suivants: un caractère de saut de ligne "\ n" (U + 000A), un caractère de retour chariot "\ r" (U + 000D) ou un retour chariot suivi immédiatement d'un saut de ligne "\ r \ n "(U + 000D U + 000A). Une ligne est soit une séquence de zéro ou plusieurs caractères suivis d'un terminateur de ligne, soit une séquence d'un ou plusieurs caractères suivie de la fin de la chaîne. Une ligne n'inclut pas le terminateur de ligne.

Avec cela, on peut simplement faire:

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

alors si vous voulez un tableau:

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

Étant donné que cette méthode renvoie un flux, elle propose de nombreuses options pour vous, car elle permet d'écrire une expression concise et déclarative d'opérations éventuellement parallèles.

Ousmane D.
la source
7

Peut-être que cela fonctionnerait:

Supprimez les doubles barres obliques inverses du paramètre de la méthode de fractionnement:

split = docStr.split("\n");
Michael
la source
8
Pas vraiment. Lorsque vous écrivez une expression régulière sous la forme d'un littéral de chaîne Java, vous pouvez utiliser "\ n" pour transmettre au compilateur d'expression régulière un symbole de saut de ligne ou "\\ n" pour lui transmettre la séquence d'échappement d'un saut de ligne. Il en va de même pour tous les autres espaces blancs à l'exception de \ v, qui n'est pas pris en charge dans les littéraux Java.
Alan Moore
3
@Yuval. Désolé, c'est faux, vous n'en avez pas du tout besoin "Contre-obliques, échappements et citations" docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…
angryITguy
7

Toutes les réponses données ici ne respectent en fait pas la définition Javas des nouvelles lignes comme donnée par exemple dans BufferedReader # readline. Java accepte \n, \ret \r\ncomme nouvelle ligne. Certaines réponses correspondent à plusieurs lignes vides ou à des fichiers mal formés. Par exemple. <sometext>\n\r\n<someothertext>lors de l'utilisation [\r\n]+entraînerait deux lignes.

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

En revanche, la réponse ci-dessus a les propriétés suivantes:

  • il est conforme à la définition Javas d'une nouvelle ligne comme par exemple le BufferedReader l'utilise
  • il ne correspond pas à plusieurs nouvelles lignes
  • il ne supprime pas les lignes vides de fin
Till Schäfer
la source
6

Si, pour une raison quelconque, vous ne souhaitez pas utiliser String.split(par exemple, en raison d' expressions régulières ) et que vous souhaitez utiliser la programmation fonctionnelle sur Java 8 ou une version plus récente:

List<String> lines = new BufferedReader(new StringReader(string))
        .lines()
        .collect(Collectors.toList());
Danilo Piazzalunga
la source
Je sais que cela peut être une solution exagérée.
Danilo Piazzalunga
3
Ou String[] lines = new BufferedReader(...).lines().toArray(String[]::new);pour un tableau au lieu d'une liste. La bonne chose à propos de cette solution est qu'elle BufferedReaderconnaît toutes sortes de terminateurs similaires, donc elle peut gérer du texte dans toutes sortes de formats. (La plupart des solutions basées sur les expressions rationnelles publiées ici ne répondent pas à cet égard.)
Ted Hopp
2
Cette solution est obsolète depuis Java 11 et l'introduction de la méthode String.lines ().
leventov
4

Pour éviter que les lignes vides ne soient écrasées, utilisez:

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

Le code ci-dessus ne fait en fait rien de visible - il calcule simplement puis décharge le calcul. Est-ce le code que vous avez utilisé, ou juste un exemple pour cette question?

essayez de faire textAreaDoc.insertString (int, String, AttributeSet) à la fin?

Chii
la source
insertUpdate () est une méthode DocumentListener. En supposant que l'OP l'utilise correctement, essayer de modifier le document à partir de la méthode d'écoute générera une exception. Mais vous avez raison: le code de cette question ne fait rien.
Alan Moore
2

Comme alternative aux réponses précédentes, l' SplitterAPI de goyave peut être utilisée si d'autres opérations doivent être appliquées aux lignes résultantes, comme le découpage des lignes ou le filtrage des lignes vides:

import com.google.common.base.Splitter;

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

Notez que le résultat est un Iterableet non un tableau.

Thomas Naskali
la source
1

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

husayt
la source
1

Après des tentatives infructueuses sur la base de toutes les solutions données. Je remplace \npar un mot spécial puis je me sépare. Pour moi, la suite a fait l'affaire:

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

Je n'ai pas pu reproduire l'exemple donné dans la question. Mais, je suppose que cette logique peut être appliquée.

kravi
la source
1

Les réponses ci-dessus ne m'ont pas aidé sur Android, grâce à la réponse Pshemo qui a fonctionné pour moi sur Android. Je vais laisser une partie de la réponse de Pshemo ici:

split("\\\\n")
clasher
la source
0
  • essayez cet espoir, il vous a été 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");
Vishal Yadav
la source
0

Il existe trois conventions différentes (on pourrait dire que ce sont des normes de facto ) pour définir et afficher un saut de ligne:

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

Dans certains éditeurs de texte, il est possible d'échanger l'un contre l'autre:

Bloc-notes ++

La chose la plus simple est de normaliser line feedpuis de diviser.

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

Il y a un nouveau garçon dans la ville, vous n'avez donc pas besoin de faire face à toutes les complexités ci-dessus. À partir de JDK 11 , il suffit d'écrire en une seule ligne de code, il divisera les lignes et vous renverra un flux de chaîne.

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

Quelques références. 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 /

J'espère que cela sera utile à quelqu'un. Codage heureux.

Garçon rouge
la source
-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]);
        }
    }

}
Naveen
la source
Cela pâlit par rapport aux autres réponses, qui sont plus explicatives et moins lourdes de code. Pourriez-vous expliquer ce que vous accomplissez avec ce code et pourquoi il ferait une réponse appropriée?
Makoto
2
Cela n'a rien à voir avec la division d'un fichier en lignes. Pensez à retirer votre réponse.
Martin