Java Dizesini New Line'a Böl


389

Ben JTextAreatarafından String bölmek için bir regex kullanarak metin bölmek çalışıyorum \nAncak, bu işe yaramaz ve ben de denedi \r\n|\r|nve regexes birçok diğer kombinasyonu. Kod:

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
aldığınız hata nedir? Dont "çalışmıyor", bu bir şey ifade etmez. Aldığınız hatayı / sonucu bize bildirin. Kod hata ayıklamasının ilk adımı budur - yanlış sonucun ne olduğunu ve programınızın buna nasıl geldiğini anlayın.
Chii

Gerçekten ne yapmak istiyorsun? - satırları JTextArea girilir gibi? - JTextArea satır kaydırma nerede yapıyor bulmak? - ???
user85421

Yanıtlar:


732

Bu sizi kapsamalıdır:

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

Endişelenmeniz gereken sadece iki yeni satır (UNIX ve Windows) var.


43
JTextArea belgesi yalnızca '\ n' KULLANMALIDIR; Onun görüşleri tamamen '\ r' görmezden. Ancak, birden fazla tür ayırıcı arayacaksanız, üçünü de arayabilirsiniz: "\ r? \ N | \ r".
Alan Moore

10
Mac 9 \ r kullanır. OSX 10, \ n
Raekye

$ {fn: uzunluk (fn: bölünmüş (veri, '\\ r? \\ n'))} jstl'de çalışmıyor

4
@antak yes, splitvarsayılan olarak bölünmüş sonuca yol açarlarsa boş dizeleri kaldırır. Bu mekanizmayı kapatmak için, split(regex, limit)gibi aşırı limitli aşırı yüklü sürümünü kullanmanız gerekir text.split("\\r?\\n", -1). Daha fazla bilgi: Java String split boş değerleri kaldırdı
Pshemo

1
@Stivlo'nun yorumu yanlış bilgilerdir ve çok fazla oyu olması talihsiz bir durumdur. @ Raekye'nin belirttiği gibi, OS X (şimdi macOS olarak bilinir) 2001'de piyasaya sürüldüğünden beri hat ayırıcısı olarak \ n kullandı. Mac OS 9 1999'da piyasaya sürüldü ve Mac OS 9 veya daha düşük bir makinenin kullanıldığını hiç görmedim üretimde. Hat ayırıcı olarak kullanılan tek bir modern işletim sistemi yoktur. ASLA Mac'te satır ayırıcı olmasını beklemeyen bir kod yazmayın, a) retro bilgi işlem yapmadığınız sürece, b) bir OS 9 makinesinin döndürülmüş olması ve c) makinenin aslında OS 9 olduğunu güvenilir bir şekilde belirleyemez.
James McLaughlin

132

String#split​(String regex)yöntemi normal ifadeyi (normal ifadeler) kullanmaktır. Java 8 normal ifadesi aşağıdakileri \Rtemsil ettiğinden (Pattern sınıfının belgelerinden ):

Linebreak eşleştirici
\ R Herhangi bir Unicode linebreak dizisi, \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Yani bunu eşleştirmek için kullanabiliriz:

Gördüğünüz gibi \r\n, normal ifadenin bu çifti eşleştirmeye çalışmasını sağlayan normal ifade başlangıcına yerleştirilir ve yalnızca bu eşleşme başarısız olursa, tek karakter satırı ayırıcılarını eşleştirmeye çalışır .


Yani ayırmak istiyorsanız satır ayırıcı kullanın split("\\R").

Eğer varsa boş dizeler sondaki diziyi çıkan kaldırmak istemiyoruz"" kullanmak split(regex, limit)negatif ile limitbenzeri parametresi split("\\R", -1).

Bir veya daha fazla işlem yapmak istiyorsanız boş satırları tek sınırlayıcı olarak kullanın split("\\R+").


4
Evet, en iyi cevap bu. Sorunun bu cevap için altı yıl çok erken sorulduğu talihsiz.
Dawood ibn Kareem

Yalnız \\R+ele alınmayan satır sonu karakterlerinden kaçınmak için ayrıldım \\R.
SeverityOne

128

Boş satırlar istemiyorsanız:

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

4
çift ters eğik çizgi, gereksizdir bölümüne bakın "ters eğik, kaçar ve alıntı" docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/...
angryITguy


1
Yukarıdaki yanıt gelmediğinde bu Mac OSX üzerinde çalıştı.
John

Bu da benim için çalıştı. Mükemmel çözüm. Aşağıdaki 2 vaka için çalıştı: 1) saat 3'te uyandım. \ R \ n \ r \ nIyi 2) bu gerçek hayat \ r \
nso

2
@tresf Nicelikleri köşeli parantez içinde kullanamazsınız.
CX oyuncusu

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

Bu sistemden bağımsız olmalıdır


41
Bu ilginç bir fikir, ancak metnin aslında sistemin satır ayırıcısını kullanmasına dikkat etmelisiniz. "Windows" ayırıcıları kullanan unix (ör. XML) ve birçok altında unix ayırıcıları kullanan Windows altında birçok metin dosyası var.
Maarten Bodewes

Android'de bile çalışır
ruX

6
Windows işletim sisteminde oluşturulan ve bir Unix işletim sistemine aktarılan dosyalar hala \ r \ n ayırıcıları içerecektir. Güvenli oynamak ve her iki ayırıcıyı hesaba katmak daha iyi olduğunu düşünüyorum.
bvdb

17
Bu çok sorunlu bir yaklaşım! Dosya kodu çalıştıran sistemden gelmeyebilir. Bu tür "sistemden bağımsız" tasarımları, özellikle belirli bir sisteme, çalışma zamanı sistemine bağlı olarak şiddetle tavsiye ederim.
Martin

4
@Shervin Bunu yapmanın en iyi yolu asla. Aslında çok kötü bir uygulamadır. System.setProperty ("line.separator", "anlamsız" diyen başka bir programcı düşünün; Kodunuz bozuk. Buna benzer bir bilginiz olmayan bir bağımlılık da denebilir.
Martin

14

Yeni bir yöntem linestanıtıldı Stringsınıfdöndüren Stream<String>

Satır sonlandırıcıları tarafından bölünmüş bu dizeden çıkarılan bir alt dize akışı döndürür.

Tanınan satır sonlandırıcılar satır besleme "\ n" (U + 000A), satır başı "\ r" (U + 000D) ve satır başı ve hemen ardından satır besleme "\ r \ n" (U + 000D U + 000A) ).

İşte birkaç örnek:

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

Yaylı # hatları ()


12

Karakter gruplarındaki karakterlerden iki kez kaçmak zorunda değilsiniz.

Boş olmayan tüm satırlar için:

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

Evet yaparsın. Herhangi bir yerde çift kaçmaya ihtiyaç duyarlarsa, her yere ihtiyaç duyarlar. Boşluk kaçar \rve \nbir veya iki ters eğik çizgiye sahip olabilir; her iki şekilde de çalışırlar.
Alan Moore

2
Koddaki çift ters eğik çizgi '\\'bir '\'karakter haline gelir ve daha sonra RegEx motoruna geçirilir, bu nedenle "[\\r\\n]"kodda [\r\n]bellek olur ve RegEx bunu işler. Java'nın RegEx'i tam olarak nasıl işlediğini bilmiyorum, ancak "saf" ASCII dize desenini RegEx motoruna iletmek ve ikili karakterleri geçmek yerine işlemesine izin vermek iyi bir uygulamadır. bellekte "[\r\n]"(onaltılık) olur 0D0Ave bir RegEx motoru onu kabul ederken diğeri boğulur.
Sonuç olarak

10

Olarak sınıf bir sahiptir yöntem:JDK11Stringlines()

Satır sonlandırıcılarla ayrılmış, bu dizeden ayıklanan satır akışını döndürme.

Ayrıca, belgeler şunları söylemeye devam ediyor:

Bir çizgi sonlandırıcı aşağıdakilerden biridir: bir satır besleme karakteri "\ n" (U + 000A), satır başı karakteri "\ r" (U + 000D) veya satır başı karakteri hemen satır satırından sonra "\ r \ n "(U + 000D U + 000A). Bir satır, sıfır veya daha fazla karakterden oluşan bir sıra ve ardından bir satır sonlandırıcıdır veya dizenin sonundan sonra bir veya daha fazla karakterden oluşan bir dizidir. Satır, satır sonlandırıcı içermez.

Bununla sadece şunları yapabilirsiniz:

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

bir dizi istiyorsanız:

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

Bu yöntem göz önüne alındığında , muhtemelen paralel işlemlerin özlü ve bildirimsel bir ifadesini yazabilmesini sağladığı için sizin için birçok seçenek üzerinde bir Akış döndürür .


7

Belki bu işe yarar:

Çift ters eğik çizgiyi split yönteminin parametresinden kaldırın:

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

8
Pek sayılmaz. Bir Java String değişmezi biçiminde bir regex yazdığınızda, regex derleyicisine bir satır besleme sembolü iletmek için "\ n" veya bir satır besleme için çıkış sırasını iletmek için "\\ n" kullanabilirsiniz. Aynı şey, Java değişmez değerlerinde desteklenmeyen \ v dışında tüm diğer boşluklardan kaçar.
Alan Moore

3
@Yuval. Maalesef yanlış, buna hiç ihtiyacınız yok "Ters eğik çizgiler
angryITguy

7

Burada verilen tüm cevaplar, örneğin BufferedReader # readline'da verilen yeni satırların Javas tanımına saygı göstermez. Java kabul etmektedir \n, \rve \r\nyeni bir satır olarak. Yanıtların bazıları birden çok boş satırla veya hatalı biçimlendirilmiş dosyayla eşleşiyor. Örneğin. <sometext>\n\r\n<someothertext>kullanırken [\r\n]+iki satır ile sonuçlanır.

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

Buna karşılık, yukarıdaki cevap aşağıdaki özelliklere sahiptir:

  • BufferedReader'ın kullandığı gibi yeni bir satırın Javas tanımına uyuyor
  • birden çok yeni satırla eşleşmiyor
  • sondaki boş satırları kaldırmaz

6

Herhangi bir nedenle, String.split(örneğin, düzenli ifadeler nedeniyle ) kullanmak istemiyorsanız ve Java 8 veya daha yeni sürümlerde işlevsel programlamayı kullanmak istiyorsanız:

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

Bunun aşırı bir çözüm olabileceğini biliyorum.
Danilo Piazzalunga

3
Veya String[] lines = new BufferedReader(...).lines().toArray(String[]::new);liste yerine bir dizi için. Bu çözümün güzel yanı, BufferedReaderher türlü benzer sonlandırıcıyı bilmesidir, böylece metni her türlü formatta işleyebilir. (Burada yayınlanan normal ifade tabanlı çözümlerin çoğu bu bağlamda yetersiz
Ted Hopp

2
Java 11 ve String.lines () yönteminin kullanılmaya başlanmasından bu yana bu çözüm geçersizdir.
leventov

4

Boş hatların ezilmeye karşı korunması için:

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

3

Yukarıdaki kod aslında görünür bir şey yapmaz - sadece hesaplar sonra hesaplar dökümü. Kullandığınız kod mu, yoksa sadece bu soru için bir örnek mi?

sonunda textAreaDoc.insertString (int, String, AttributeSet) yapmayı deneyin?


insertUpdate () bir DocumentListener yöntemidir. OP'nin doğru kullandığını varsayarsak, belgeyi dinleyici yönteminden değiştirmeye çalışmak bir istisna oluşturur. Ama haklısın: bu sorudaki kod aslında hiçbir şey yapmıyor.
Alan Moore

2

Önceki yanıtlara alternatif olarak, Splittersonuç satırlarına kırpma çizgileri veya boş satırları filtreleme gibi başka işlemler uygulanacaksa guava'nın API'si kullanılabilir:

import com.google.common.base.Splitter;

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

Sonucun Iterablebir dizi değil, bir dizi olduğunu unutmayın.


1

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


1

Verilen tüm çözümler temelinde başarısız denemelerden sonra. \nBazı özel kelimelerle değiştiriyorum ve sonra bölüyorum. Benim için aşağıdaki hile yaptı:

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

Soruda verilen örneği tekrarlayamadım. Ama sanırım bu mantık uygulanabilir.


1

Yukarıdaki yanıtlar, Android'de benim için çalışan Pshemo yanıtı sayesinde Android'de bana yardımcı olmadı . Pshemo'nun cevabından bazılarını burada bırakacağım :

split("\\\\n")

0
  • bu umudunu dene senin için yararlı oldu

 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

Satır sonu oluşturmak ve görüntülemek için üç farklı sözleşme (bunların fiili standartlar olduğu söylenebilir ) vardır:

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

Bazı metin editörlerinde, birini diğeriyle değiştirmek mümkündür:

Notepad ++

En basit şey normalleşmek line feedve sonra bölünmektir.

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

0

Şehirde yeni bir çocuk var, bu yüzden yukarıdaki tüm karmaşıklıklarla uğraşmanıza gerek yok. JDK 11'den itibaren , tek bir kod satırı olarak yazmanız yeterlidir, satırları böler ve size String Akışı döndürür.

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

Bazı referanslar. https://docs.oracle.com/tr/java/javase/11/docs/api/java.base/java/lang/String.html#lines () https://www.azul.com/90-new -özellikler-ve-apis-in-JDK-11 /

Umarım bu birisine yardımcı olur. Mutlu kodlama.


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

}

Bu, daha açıklayıcı ve daha az kod ağırlıklı olan diğer cevaplara kıyasla söner. Bu kodla neyi başardığınızı ve neden uygun bir cevap vereceğini açıklayabilir misiniz?
Makoto

2
Bunun bir dosyayı satırlara ayırmakla ilgisi yoktur. Cevabınızı kaldırmayı düşünün.
Martin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.