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

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.


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+").


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

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


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


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

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.


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

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

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

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

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?


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.


1

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


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.


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

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

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

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.


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

}

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.