नई लाइन द्वारा स्प्लिट जावा स्ट्रिंग


388

मैं JTextAreaस्ट्रिंग को विभाजित करने के लिए एक regex के उपयोग से पाठ को विभाजित करने की कोशिश कर रहा हूं \n, हालांकि, यह काम नहीं करता है और मैंने \r\n|\r|nऔर regexes के कई अन्य संयोजन द्वारा भी कोशिश की है । कोड:

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 लाइन wraps कर रहा है? - ???
user85421

जवाबों:


731

यह आपको कवर करना चाहिए:

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

वास्तव में केवल दो नए समाचार (UNIX और Windows) हैं जिनके बारे में आपको चिंता करने की आवश्यकता है।


43
एक JTextArea दस्तावेज़ SHOULD केवल '\ n' का उपयोग करता है; इसके दृश्य पूरी तरह से '\ r' को अनदेखा करते हैं। लेकिन अगर आप एक से अधिक विभाजक की तलाश में हैं, तो आप तीनों को देख सकते हैं: "\ r! \ N | \ r"।
एलन मूर

10
मैक 9 \ r का उपयोग करता है। OSX 10 का उपयोग करता है \ n
Raekye

$ {fn: लंबाई (fn: विभाजित (डेटा, '\\ r? \\ n'))} jstl में काम नहीं कर रहा है

4
@antak हाँ, splitडिफ़ॉल्ट रूप से खाली स्ट्रिंग्स को हटा देता है यदि वे विभाजन का परिणाम देते हैं। इस तंत्र को बंद करने के लिए आपको split(regex, limit)नकारात्मक सीमा जैसे ओवरलोडेड संस्करण का उपयोग करने की आवश्यकता है text.split("\\r?\\n", -1)। अधिक जानकारी: जावा स्ट्रिंग स्प्लिट ने खाली मान हटा दिए
Pshemo

1
@Stivlo द्वारा की गई टिप्पणी गलत सूचना है, और यह दुर्भाग्यपूर्ण है कि इसमें बहुत सारे बदलाव हैं। जैसा कि @ Raekye ने बताया, OS X (जिसे अब macOS के रूप में जाना जाता है) ने 2001 में रिलीज़ होने के बाद से इसकी लाइन विभाजक के रूप में \ n का उपयोग किया है। Mac OS 9 को 1999 में रिलीज़ किया गया था, और मैंने कभी भी Mac OS 9 या इससे नीचे की मशीन का उपयोग नहीं किया है उत्पादन में। एक भी आधुनिक ऑपरेटिंग सिस्टम नहीं है जो लाइन विभाजक के रूप में \ r का उपयोग करता है। कभी भी ऐसा कोड न लिखें, जो मैक पर लाइन सेपरेटर होने की उम्मीद करता है, जब तक कि आप) आप रेट्रो कंप्यूटिंग में नहीं हैं, बी) के पास एक ओएस 9 मशीन है, और सी) मज़बूती से यह निर्धारित कर सकता है कि मशीन वास्तव में ओएस 9. है
जेम्स

132

String#split​(String regex)विधि regex (नियमित अभिव्यक्ति) का उपयोग कर रही है। चूंकि Java 8 regex समर्थन करता है \Rजो प्रतिनिधित्व करता है ( पैटर्न वर्ग के प्रलेखन से ):

लाइनब्रेक माचिस
आर किसी भी यूनिकोड लाइनब्रेक अनुक्रम के बराबर है \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

तो हम इसका उपयोग मैच के लिए कर सकते हैं:

जैसा कि आप देख रहे हैं \r\nकि रेगेक्स की शुरुआत में रखा गया है, जो यह सुनिश्चित करता है कि रेगेक्स पहले इस जोड़ी से मेल खाने की कोशिश करेगा , और केवल अगर यह मैच विफल हो जाता है तो यह सिंगल कैरेक्टर लाइन सेपरेटर से मेल खाने की कोशिश करेगा ।


इसलिए यदि आप लाइन सेपरेटर उपयोग पर विभाजित करना चाहते हैं split("\\R")

यदि आप परिणामी सरणी से निकालना नहीं चाहते"" हैं तो खाली स्ट्रिंग का उपयोग करें जैसे कि split(regex, limit)नकारात्मक limitपैरामीटर के साथ split("\\R", -1)

यदि आप एक या एक से अधिक उपचार करना चाहते हैं तो एक सीमांकक के रूप में खाली लाइनों को जारी रखना चाहिए split("\\R+")


4
हाँ, यह सबसे अच्छा जवाब है। दुर्भाग्यपूर्ण है कि इस उत्तर के लिए प्रश्न छह साल पहले भी पूछा गया था।
दाऊद इब्न करीम

मैंने \\R+किसी भी अंत वर्णों से बचने के लिए विभाजन को समाप्त किया, जो \\Rअकेले कवर नहीं थे ।
सेवेरिटीऑन

128

यदि आप खाली लाइनें नहीं चाहते हैं:

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

4
डबल बैकस्लैश अनावश्यक हैं, खंड "बैकस्लैश, एस्के
javase/


1
यह मैक ओएसएक्स पर काम करता था जब उपरोक्त उत्तर नहीं था।
जॉन

यह भी मेरे लिए काम किया। उत्कृष्ट समाधान। इसके बाद के 2 मामलों के लिए काम किया: 1) मैं 3 ओ घड़ी में जाग गया। \ r \ n \ r \ n आशा 2) यह वास्तविक जीवन \ r \ n है I
logixplayer

2
@tresf आप वर्ग कोष्ठक में मात्रा का उपयोग नहीं कर सकते।
सीएक्स गेमर

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

यह प्रणाली स्वतंत्र होनी चाहिए


41
यह एक दिलचस्प विचार है, लेकिन आपको ध्यान रखना चाहिए कि पाठ वास्तव में सिस्टम के लाइन विभाजक का उपयोग करता है। मैंने यूनिक्स (जैसे एक्सएमएल) के तहत कई कई पाठ फ़ाइलों को अच्छा किया है जो "विंडोज" विभाजकों का उपयोग करता है और विंडोज के तहत कुछ ऐसे हैं जो यूनिक्स विभाजकों का उपयोग करते हैं।
मार्टन बॉड्यूज

यहां तक ​​कि एंड्रॉइड पर काम करता है
ruX

6
विंडोज़ ओएस में बनाई गई फाइलें और एक यूनिक्स ओएस में स्थानांतरित करने के बाद भी \ r \ n सेपरेटर शामिल होंगे। मुझे लगता है कि सेफ खेलना और दोनों सेपरेटरों को ध्यान में रखना बेहतर है।
bvdb

17
यह एक बहुत समस्याग्रस्त दृष्टिकोण है! फ़ाइल कोड को चलाने वाले सिस्टम से उत्पन्न नहीं हो सकती है। मैं दृढ़ता से इन प्रकार के "सिस्टम स्वतंत्र" डिजाइनों को हतोत्साहित करता हूं जो वास्तव में एक विशिष्ट सिस्टम, रनटाइम सिस्टम पर निर्भर करता है।
मार्टिन

4
@ शेरविन यह करने का सबसे अच्छा तरीका कभी नहीं है। यह वास्तव में बहुत बुरा अभ्यास है। System.setProperty ("line.separator", "आपके पास कोई बिंदु नहीं") कॉल करने वाले कुछ अन्य प्रोग्रामर पर विचार करें; आपका कोड टूट गया है यहां तक ​​कि इसे उसी तरह से निर्भरता कहा जा सकता है जिसके बारे में आपको कोई जानकारी नहीं है।
मार्टिन

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

स्ट्रिंग # लाइनें ()


12

आपको चरित्र समूहों में वर्णों को दोहराकर बचाना नहीं है।

सभी गैर खाली लाइनों के लिए:

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

हाँ आप कीजिए। अगर उन्हें कहीं भी डबल-भागने की ज़रूरत है, तो उन्हें हर जगह इसकी ज़रूरत है। व्हॉट्सएप की तरह बच जाता है \rऔर \nएक या दो बैकस्लैश हो सकते हैं; वे दोनों तरह से काम करते हैं।
एलन मूर

2
'\\'कोड में डबल बैकस्लैश एक '\'चरित्र बन जाता है और फिर RegEx इंजन को पास कर दिया "[\\r\\n]"जाता है , इसलिए कोड [\r\n]मेमोरी में हो जाता है और RegEx इसे प्रोसेस करेगा। मुझे नहीं पता है कि जावा वास्तव में RegEx को कैसे संभालता है, लेकिन RegEx इंजन के लिए "शुद्ध" ASCII स्ट्रिंग पैटर्न को पास करना और बाइनरी वर्णों को पारित करने के बजाय इसे प्रोसेस करने देना एक अच्छा अभ्यास है। स्मृति में "[\r\n]"(हेक्स) हो जाता है 0D0Aऔर एक RegEx इंजन इसे स्वीकार कर सकता है जबकि दूसरा घुट जाएगा। तो लब्बोलुआब यह है कि भले ही जावा के RegEx के स्वाद की जरूरत नहीं है, संगतता के लिए डबल स्लैश रखें
nuri

10

में कक्षा एक है विधि:JDK11Stringlines()

इस स्ट्रिंग से निकाली गई लाइनों की एक धारा को लौटाते हुए, लाइन टर्मिनेटर्स द्वारा अलग किया जाता है।

इसके अलावा, प्रलेखन कहने के लिए आगे बढ़ता है:

एक लाइन टर्मिनेटर निम्नलिखित में से एक है: एक लाइन फीड कैरेक्टर "\ n" (U + 000A), एक कैरेज रिटर्न कैरेक्टर "\ r" (U + 000D), या एक कैरिज रिटर्न तुरंत एक लाइन फीड "\ r" के बाद आता है। \ n "(U + 000D U + 000A)। एक रेखा या तो शून्य या अधिक वर्णों का एक क्रम है, जिसके बाद एक पंक्ति टर्मिनेटर होता है, या यह एक या एक से अधिक वर्णों का क्रम होता है, जिसके बाद स्ट्रिंग का अंत होता है। एक लाइन में लाइन टर्मिनेटर शामिल नहीं है।

इस के साथ एक बस कर सकते हैं:

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

फिर यदि आप एक सरणी चाहते हैं:

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

इस पद्धति को देखते हुए यह आपके लिए बहुत सारे विकल्पों पर एक स्ट्रीम देता है क्योंकि यह संभवतः-समानांतर संचालन के संक्षिप्त और घोषणात्मक अभिव्यक्ति को लिखने में सक्षम बनाता है ।


7

शायद यह काम करेगा:

स्प्लिट विधि के पैरामीटर से डबल बैकस्लैश निकालें:

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

8
ज़रुरी नहीं। जब आप जावा स्ट्रिंग शाब्दिक के रूप में एक रेगेक्स लिखते हैं, तो आप रेगेक्स कंपाइलर को एक लाइनफीड सिंबल, या "\\ n" पास करने के लिए "\ n" का उपयोग करके उसे एक लाइनफीड के लिए एस्केप सीक्वेंस पास कर सकते हैं। वही अन्य सभी व्हाट्सएप के लिए चला जाता है, सिवाय \ v को छोड़कर, जो जावा शाब्दिकों में समर्थित नहीं है।
एलन मूर

3
@Yuval। क्षमा करें कि यह गलत है, आपको इसकी आवश्यकता नहीं है "Backslashes, es एस्केप
नाराज़गी

7

यहाँ दिए गए सभी उत्तर वास्तव में नई लाइनों की जावस परिभाषा का सम्मान नहीं करते हैं, जैसे कि बफ़रड्रेडर # रीडलाइन। जावा स्वीकार कर रहा है \n, \rऔर \r\nनई लाइन के रूप में। कुछ उत्तर कई खाली लाइनों या विकृत फ़ाइलों से मेल खाते हैं। E..g। <sometext>\n\r\n<someothertext>का उपयोग करते समय [\r\n]+दो लाइनों में परिणाम होगा।

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

इसके विपरीत, उपरोक्त उत्तर में निम्नलिखित गुण हैं:

  • यह एक नई लाइन की Javas परिभाषा का अनुपालन करता है जैसे कि BufferedReader इसका उपयोग कर रहा है
  • यह कई नई लाइनों से मेल नहीं खाता है
  • यह खाली लाइनों को पीछे नहीं हटाता है

6

यदि, किसी कारण से, आप String.split(उदाहरण के लिए, नियमित अभिव्यक्तियों के कारण ) का उपयोग नहीं करना चाहते हैं और आप जावा या 20 पर कार्यात्मक प्रोग्रामिंग का उपयोग करना चाहते हैं:

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

मुझे पता है कि यह एक ओवरकिल समाधान हो सकता है।
डैनिलो पियाज़ालुंगा 19

3
या String[] lines = new BufferedReader(...).lines().toArray(String[]::new);सूची के बजाय एक सरणी के लिए। इस समाधान के बारे में अच्छी बात यह है कि BufferedReaderसभी प्रकार के टर्मिनेटर के बारे में पता है, इसलिए यह सभी प्रकार के प्रारूपों में पाठ को संभाल सकता है। (रेगेक्स-आधारित समाधानों के अधिकांश यहां पोस्ट किए गए इस संबंध में कम हैं।)
टेड हॉप

2
यह समाधान जावा 11 और String.lines () पद्धति की शुरूआत के बाद से अप्रचलित है।
लेवेंटोव

4

खाली लाइनों को स्क्वैश के उपयोग से बचाने के लिए:

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

3

उपर्युक्त कोड वास्तव में कुछ भी दिखाई नहीं देता है - यह केवल कैलक्लिप्स की गणना करता है। क्या यह आपके द्वारा उपयोग किया गया कोड है, या इस प्रश्न के लिए सिर्फ एक उदाहरण है?

आखिर में textAreaDoc.insertString (int, String, AttributeSet) करने की कोशिश करें?


InsertUpdate () एक DocumentListener विधि है। मान लें कि ओपी इसका सही उपयोग कर रहा है, तो श्रोता विधि के भीतर से दस्तावेज़ को संशोधित करने की कोशिश एक अपवाद उत्पन्न करेगी। लेकिन आप सही हैं: उस प्रश्न में कोड वास्तव में कुछ भी नहीं करता है।
एलन मूर

2

पिछले उत्तरों के विकल्प के रूप में, अमरूद के Splitterएपीआई का उपयोग किया जा सकता है यदि अन्य परिचालनों को परिणामी लाइनों पर लागू किया जाना है, जैसे लाइनों को ट्रिम करना या खाली लाइनों को फ़िल्टर करना:

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

एक लाइन ब्रेक को प्रदर्शित करने और प्रदर्शित करने के लिए तीन अलग-अलग सम्मेलन हैं (यह कहा जा सकता है कि वे वास्तविक मानक हैं):

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

कुछ पाठ संपादकों में, एक को दूसरे के लिए विनिमय करना संभव है:

Notepad ++

सबसे सरल बात यह है कि सामान्य करना line feedऔर फिर विभाजन करना।

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

0

कस्बे में नया लड़का है, इसलिए आपको उपरोक्त सभी जटिलताओं से निपटने की आवश्यकता नहीं है। JDK 11 के बाद से , बस कोड की एक पंक्ति के रूप में लिखने की आवश्यकता है, यह लाइनों को विभाजित करेगा और आपको स्ट्रिंग ऑफ स्ट्रीम लौटाएगा।

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 और APIs में 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
इसका किसी फ़ाइल को लाइनों में विभाजित करने से कोई लेना-देना नहीं है। अपने उत्तर को हटाने पर विचार करें।
मार्टिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.