# Zeilenumbruch erkennen



## BlackViruZ (9. Feb 2009)

Hallo ihr Entwickler!
Also, ich muss in einem Programm Text-Input (von einem JTextArea, also String) verarbeiten und dabei auch Zeilenansätze erkennen - das Problem:
Ich benutze einen StringTokenizer, lediglich mit den Begrenzern *Leerzeichen* und *String.format("%n")* (möchte es Plattform unabhängig machen).
Da auch Namen mit Leerzeichen vorkommen können, lass ich die Begrenzer mit ausgeben daher:

```
final String delim1 = " ", delim2 = String.format("%n");
		StringTokenizer buffer = new StringTokenizer(input, delim1 + delim2,
				true);
```
Soweit so gut, nur wenn ich jetzt mir die Tokens wieder geben lasse (per nextToken) und feststellen will, ob es sich um einen Zeilenumbruch handelt funktioniert es nicht

```
do {
	token = buffer.nextToken();
} while (token.equals(delim1)
	|| token.equals(delim2));
```
Dies klappt nicht!!!
Ich musste *token.equals(delim2) gegen token.equals("\n")* austauschen, damit der Zeilenumbruch erkannt wird -
das macht es natürlich _Plattformabhängig_.
Kann mir jmd da helfen?

MfG Blacky


----------



## Ariol (9. Feb 2009)

System.getProperty("line.separator")


----------



## BlackViruZ (9. Feb 2009)

Ariol hat gesagt.:
			
		

> System.getProperty("line.separator")


Habe es ausprobiert - funktioniert nicht


----------



## Ariol (9. Feb 2009)

Ähm, hab mir grad deinen ersten Eintrag noch mal durchgelesen.

JTextField kann nur eine Reihe Code haben - da ist nichts mit "\n"
Bei anderen(JTextArea) sollte es so funktionieren.


```
input.split(System.getProperty("line.separator"))
```




			
				http://java.sun.com/javase/6/docs/api/java/util/StringTokenizer.html hat gesagt.:
			
		

> StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split  method of String or the java.util.regex package instead.
> 
> The following example illustrates how the String.split method can be used to break up a string into its basic tokens:
> 
> ...


----------



## BlackViruZ (9. Feb 2009)

Ariol hat gesagt.:
			
		

> Ähm, hab mir grad deinen ersten Eintrag noch mal durchgelesen.
> 
> JTextField kann nur eine Reihe Code haben - da ist nichts mit "\n"
> Bei anderen(JTextArea) sollte es so funktionieren.
> ...



Joa hatte mich vertippt, es aber vor ein paar minuten korrigiert (haben uns wohl verpasst^^)
Also ich benutze in der Tat eine JTextArea
Bei der split Methode weiß ich aber nicht genau wie ich anstellen kann, was ich möchte, denn ich brauche ja (wie oben gesagt) auch die zeichen, welche als begrenzung eingegeben sind


----------



## Ariol (9. Feb 2009)

Und? Split benutzt regex:


```
String test = "Hallo\nWie geht es denn?";
	String[] lines = test.split("\\s|" + System.getProperty("line.separator"));
	for(int i = 0; i < lines.length; i++)
	{
		System.out.println(i + ":" + lines[i]);
	}
```

Ausgabe:

```
0:Hallo
1:Wie
2:geht
3:es
4:denn?
```


----------



## BlackViruZ (9. Feb 2009)

ich bräuchte eher
0:Hallo 1: 
2:wie 3:  4:geht 5: 6:es 7: 8:denn?

Da liegt der Hase begraben^^
Ich habe nämlich keine Ahnung wie ich die Begrenzungen mit regex als eigenen "Token" ausgeben lassen soll


----------



## Spacerat (9. Feb 2009)

Versuchs mal mit dem Grossen Bruder des StringTokenizers, dem StreamTokenizer. Dort kann man allerdings nur einzelne Zeichen als Token definieren. Deswegen kann z.B. der MS-Dos Zeilenumbruch ("\n\r" oder vllt. doch andersrum??) nur mit einem "Trick" (der "pushBack()"-Methode) erfolgreich erkannt werden.

mfg Spacerat


----------



## BlackViruZ (9. Feb 2009)

Spacerat hat gesagt.:
			
		

> Versuchs mal mit dem Grossen Bruder des StringTokenizers, dem StreamTokenizer. Dort kann man allerdings nur einzelne Zeichen als Token definieren. Deswegen kann z.B. der MS-Dos Zeilenumbruch ("\n\r" oder vllt. doch andersrum??) nur mit einem "Trick" (der "pushBack()"-Methode) erfolgreich erkannt werden.
> 
> mfg Spacerat


Hakt es im Endeffekt dann nicht wieder mit der Plattform-unabhängigkeit?
Das ist ja schließlich das einzige Problem, die Windows-Variante funktioniert schon^^


----------



## Spacerat (10. Feb 2009)

Nee... Der Trick ist eigentlich nur der, dass wenn ein "\r" gelesen wird, darauf getestet werden muss, ob darauf ein "\n" folgt. Das bedeutet, das das nächste Zeichen gelesen werden muss. Ist es ein "\n" handelt es sich um einen MS-Dos-Zeilenumbruch ("\r\n" so rum ist's richtig  ). Ist es kein "\n" muss das Zeichen mit "pushBack()" zurückgelegt werden.

mfg Spacerat


----------



## BlackViruZ (10. Feb 2009)

Ich meinte ja auch eher wegen der Formulierung "MS-Dos",
wie kann ich denn dann für Plattform-Unabhängigkeit sorgen? 
(Muss ich mir die dafür kompletten Zeilenumbruchs-Indikatoren von den verbreiteten Plattformen rausschreiben?!)


----------



## mahe (10. Feb 2009)

Sind ja nur drei verschiedene Kombinationen mit zwei "Zeichen":

Mac: CR
Linux: LF
Windows: CR+LF


----------



## Spacerat (10. Feb 2009)

Würd' ich mal mit Ja beantworten. Aber keine Panik. Ich weiss zwar nicht wie der Zeilenumbruch bei MacOS aussieht, aber Windows stellt in diesem Fall wohl eine Ausnahme dar, weil der ZU auf allen anderen Systemen die ich kenne eben nur das LineFeed ("\n") ist.

mfg Spacerat

@Edit: War da wieder jemand schneller... und das auch noch mit 'ner vollständigeren Aussage... Danke für die Info.


----------



## BlackViruZ (10. Feb 2009)

Okay, dann danke für die Hilfe,
Ich probiere das ganze später und kümmer mich jetzt erstmal um den Rest-Quellcode (vorab Windows-basierend^^)
Die umstellung auf die anderen Platformen mache ich dann später (ich verschiebe es erst mal mich damit rum-zuschlagen^^)
Falls ich noch Probleme damit haben sollte - mach ich mal ne wiederbelebung von dem Thread hier^^

MfG & lg der Black!


----------



## didjitalist (10. Feb 2009)

lass java die ganze arbeit tun. stopf den den string in einen CharArrayReader und lies die zeilen dann mit nem BufferedReader.


----------



## BlackViruZ (10. Feb 2009)

Ansich die Idee ist ganz nett, um so mit Readline einfach eine Zeile zu lesen - dann wüsste man ja auch das am Ende des Strings ein Zeilenumbruch wäre - aber ich glaube ich benutze lieber die andere Variante (auf \n, \r und \n\r zu überprüfen - da ich schon an der Windows-only Variante gearbeitet habe ist es so einfacher (ansonsten müsste ich die komplette Programm-Struktur für das Parsen des input verändern -.-)
Außerdem habe ich mal beim BufferedReader API geschaut - Readline macht ja auch nichts anderes als bis zum nächsten \n, \r, \n\r zu lesen

Müsste die Abfrage auf die 3 Indikatoren nicht auch mit einem StringTokenizer funktionieren?
Der wäre mir lieber, ist einfacher zu handhaben als der StreamTokenizer 

Noch ne kleine Frage zum Schluss: WARUM hat Sun sich dazu entschlossen den StringTokenizer nur noch aus kompabiltäts-gründen in der Bibliothek zu behalten? Ist doch echt praktisch, das Ding (praktischer als String.split zumindest)


----------



## Spacerat (10. Feb 2009)

BlackViruZ hat gesagt.:
			
		

> Noch ne kleine Frage zum Schluss: WARUM hat Sun sich dazu entschlossen den StringTokenizer nur noch aus kompabiltäts-gründen in der Bibliothek zu behalten? Ist doch echt praktisch, das Ding (praktischer als String.split zumindest)


Das erfährt man ebenfalls im API: wegen "java.util.regex". Hat lange gedauert, bis SUN den Weg zu RegularExpressions gefunden hat (seit JRE1.4 lt API). Die sind noch um einiges vieles praktischer. Und aus Kompatibilitätsgründen drinnen gelassen ist gut... Für "Gewohnheits-Rechtler" nicht als "deprecated"  eingestuft triffts besser, wenn man bedenkt was da alles als solches im API rumvegetiert, damit "JRE1.0" Applikationen auch ja noch unter "JRE1.7" laufen.

mfg Spacerat


----------



## Kaffeemaschinist (10. Feb 2009)

Regular expression:
Das Token für Whitespace ist _\s_, das erkennt dann also sämtliche Sachen von Tabulator, Leerzeichen bis hin zu den drei möglichen Newline-Sequenzen.

Z.B.

```
([^\s]*)([\s]*)
```

In der ersten Gruppierung findest du dann jeweils den Text, in der zweiten die Whitespaces. Da das Ding auch auf einen leeren String anspringt, müsstest du das vorher rausnehmen.


----------



## BlackViruZ (10. Feb 2009)

Kaffeemaschinist hat gesagt.:
			
		

> Regular expression:
> Das Token für Whitespace ist _\s_, das erkennt dann also sämtliche Sachen von Tabulator, Leerzeichen bis hin zu den drei möglichen Newline-Sequenzen.


Ich muss zwischen einem Leerzeichen und einer Newline Sequenz unterscheiden, daher bringt mir das nicht viel
Ich habe jetzt einfach (zur einfacheren Handhabung) eine Methode geschrieben:

```
private boolean isNewlineToken(String token){
  return token.equals("\n")||token.equals("\r")||token.equals("\r\n");
}
```
Das funktioniert soweit ganz gut, also brauche ich keine weitere Hilfe :toll:

@EDIT: Okay, jetzt verstehe ich erst was du mit 1.Gruppe und 2.Gruppe meinst - dein Vorschlag wäre also eine Möglichkeit gewesen - wie dem auch sei (jetzt habe ich ja eine lösung^^)
Sry für das kleine Missverständniss


----------



## Spacerat (10. Feb 2009)

Das mit dem StreamTokenizer? Dann fürchte ich, das bei Windows-Dateien die neue Zeile mit einem LineFeed beginnt, da dieser nur einzelne Zeichen als Token akzeptiert. Deswegen ist 
	
	
	
	





```
equals("\r\n")
```
relativ nutzlos. Vielmehr muss bei "\r" ein weiteres Zeichen gelesen werden und wenn es nicht "\n" ist zurück geschrieben werden.

```
public boolean isNewLineToken(String token, StreamTokenizer st)
{
    if(token.equals("\n") return true;
    if(token.equals("\r") {
        st.nextToken();
        if(!st.sval.equals("\n") st.pushBack();
        return true;
    }
    return false;
}
```

mfg Spacerat


----------



## BlackViruZ (10. Feb 2009)

Spacerat hat gesagt.:
			
		

> Das mit dem StreamTokenizer? Dann fürchte ich, das bei Windows-Dateien die neue Zeile mit einem LineFeed beginnt, da dieser nur einzelne Zeichen als Token akzeptiert. Deswegen ist
> 
> 
> 
> ...



Ich benutze den StringTokenizer, nicht den StreamTokenizer


----------



## Spacerat (10. Feb 2009)

Aha...? Wer lesen kann ist klar im Vorteil??! ;-)

@Edit: me too... also vergiss den Sch...


----------



## BlackViruZ (11. Feb 2009)

np
Läuft ja, jetzt gehts in die nächste Stage^^

Dennoch danke für die schnelle (und ausführliche) Hilfe!

MfG & lg BlackViruZ


----------

