# Sonderzeichen in einem String erkennen



## speedle (2. Apr 2010)

Hallo,

ich bin leider Anfänger in Java und komme bei diesem Problem einfach nicht weiter:
Ich soll einen String auf Sonderzeichen (also alle Zahlen + Zeichen wie ", §, $, %, &, / usw.) überprüfen. Dies alles wird dann in eine boolean Methode verpackt und entweder ein true oder halt false zurückgegeben.

Mein Ansatz:

```
public static boolean containsOnlyLetters(String s) {
             for (int j = 0; j < s.length(); j++)
	if (Character.isDigit(s.charAt(j)))
	return false;
	return true;	
	}
```

Aber wie man unschwer erkennen kann, werden damit nur Zahlen abgefangen, aber halt leider keine Sonderzeichen.

Ich hoffe, dass mir jemand Hilfe geben kann!

Besten Dank schon mal!

Gruß


----------



## faetzminator (2. Apr 2010)

Machs doch mit Regex. Alle nötigen Infos findest du hier: Pattern (Java 2 Platform SE v1.4.2). Willst du z.B. prüfen, ob in einem String nur a-z, A-Z, 0-9 und _ vorkommen, hast du [c]\w[/c] zur Verfügung:

```
public static boolean containsOnlyLetters(String s) {
    return s.matches("\\w*");
}
```
für a-d würdest du [c]"[a-d]*"[/c] verwenden etc.


----------



## speedle (2. Apr 2010)

Hy,


für meine Zwecke sollte ich *\W* A non-word character: [^\w] verwenden, oder?
Also:

```
public static boolean containsOnlyLetters(String s) {
    return s.matches("\\W");
}
```

Aber leider funktioniert das nicht wirklich, weil er dann auch bei Wörtern ohne Sonderzeichen ne Fehlermeldung schmeisst!?

Gruß


----------



## faetzminator (2. Apr 2010)

du willst [c]true[/c], wenn nur Buchstaben vorkommen, also [c]true[/c] von dem Regex. Dann willst du ganz bestimmt nicht [c]"\\W*"[/c] sondern [c]"\\w*"[/c]. Ein [c]\w[/c] steht dafür für _ein_ Vorkommnis eines Buchstaben, der [c]*[/c] dahinter für 0 bis unendliche Vorkomnisse - das was du willst! Aber wie gesagt, der [c]\w[/c] matcht auf [c][a-zA-Z0-9_][/c], also auch auf 0-9 und _. Diese müsstest du ansonsten explizit ausklammern.


----------



## speedle (2. Apr 2010)

OK, Danke für deine Erläuterung. Kann man in RegEx also sowohl \w als auch \D gleichzeitig reinpacken?


----------



## faetzminator (2. Apr 2010)

Ja, du verwendest einfach [c]"[\\w\\D]*"[/c], aber \w ist sowieso in \D drin. Du würdest wohl so was wollen: [c]"[\\w&&[^\\d]]*"[/c], also a-z, A-Z und _. Mit Regex könnte man noch viel mehr


----------



## speedle (2. Apr 2010)

Hy,

also der _ darf auch net enthalten sein! 
Regex ist wirklich sehr mächtig, erfordert aber leider auch ne mächtige Einarbeitungszeit.


----------



## speedle (2. Apr 2010)

Das ganze soll für ne Uni Arbeit gemacht werden. Bin mir gar net sicher, ob die Regex akzeptieren, da wir es noch nicht behandelt haben.
Hat einer irgend ne Idee, das mit ner for Schleife oder wie auch immer zu lösen ohne den Einsatz von regex?


----------



## crackm (2. Apr 2010)

Regex sind reguläre Ausdrücke und eigentlich auch das Thema der Theoretische Infromatik 1 d.h. denke ich schon, dass es ok wäre diese zu benutzen  .
Und ja man kann es auch anderes lösen:
da du String als Parameter übergibst kannst du denn in einen char-array aufspalten. Dafür bestimmst du zunächst die Länge des Strings und erzeugst einen entsprechenden char-array(siehe charAt). Da Zeichen eine Entsprächung in einer ASCII Tabelle haben, haben die auch so ein Art id. Die Großbuchstaben befinden sich dabei zwischen 65 und 89 und Kleinbuchstaben 97 und 122.
Wenn du diesen array duchgehts und ein Zeichen mit id z.b. 95 vorkommt kannst du die Schleife abbrechen und false zurückgeben.

Edit: Kann man auch ohne array


----------



## speedle (2. Apr 2010)

Wie gesagt, da ich Anfänger bin bin ich um jeden Ratschlag dankbar.
Leider funktioniert das mit regex und den o.g. Ausdrücken nich nicht wirklich. Entweder habe ich es falsch implementiert oder aber geben die Ausdrücke noch nicht ganz Sinn?
Arrays haben wir atm noch nen behandelt ... ich weiss aber einfach nicht, wie mans ohne regex einigermassen effizient programmieren könnte!?

Gruß


----------



## eRaaaa (2. Apr 2010)

Ne doofe Frage am Rande : wieso benutzt du anstelle von Character.isDigit() nicht isLetter() ? (bzw was ist mit ä,ü,ö,ß ? Zählen die etwa als Sonderzeichen? )


----------



## speedle (2. Apr 2010)

Ganz einfach: Weil damit auch nicht alles abgefangen wird!
Es sollen Namen (Vornamen) eingelesen werden, sodass ä, ö etc. nicht wirklich sinn voll sind.


----------



## crackm (2. Apr 2010)

Mal ein Tipp am Rande ich habe da oben was hingeschrieben ^^

```
public static boolean containsOnlyLetters_2(String s) {
       for (int j = 0; j < s.length(); j++){
          if (!(((int)s.charAt(j)>=65 && (int)s.charAt(j)<=89) || ((int)s.charAt(j)>=97 && (int)s.charAt(j)<=122)) )
          {
            return false;
          }
       }
       return true;

    }
```


----------



## eRaaaa (2. Apr 2010)

speedle hat gesagt.:


> Ganz einfach: Weil damit auch nicht alles abgefangen wird!
> Es sollen Namen (Vornamen) eingelesen werden, sodass ä, ö etc. nicht wirklich sinn voll sind.



Okay, das hattest du noch nicht erwähnt, daher meine Frage. Was sinnvoll ist und was nicht, entscheidest natürlich du oder der Aufgabensteller anhand des Problems, aber an sich gibts natürlich ü,ö oder ähnliches in Vornamen (Jürgen,Jörg, ...usw) 
Aber okay,wenn ichs dann jetzt richtig verstanden habe, ist es dann wohl mit Regex ein einfaches

```
public static boolean containsOnlyLetters_3(String s) {
	return s.matches("[a-zA-Z]+");
    }
```

(obwohl du das ja anscheinend auch nicht willst...^^)


----------



## speedle (2. Apr 2010)

crackm hat gesagt.:


> Mal ein Tipp am Rande ich habe da oben was hingeschrieben ^^
> 
> ```
> public static boolean containsOnlyLetters_2(String s) {
> ...



Besten Dank! Funktioniert astrein! 





eRaaaa hat gesagt.:


> Okay, das hattest du noch nicht erwähnt, daher meine Frage. Was sinnvoll ist und was nicht, entscheidest natürlich du oder der Aufgabensteller anhand des Problems, aber an sich gibts natürlich ü,ö oder ähnliches in Vornamen (Jürgen,Jörg, ...usw)
> Aber okay,wenn ichs dann jetzt richtig verstanden habe, ist es dann wohl mit Regex ein einfaches
> 
> ```
> ...



Danke! Sehr elegant die Lösung. Ich wollte vorher immer mit den vordefinierten Ausdrücken arbeiten, aber in diesem Fall ist eine manuelle wesentlich sinnvoller.


Besten Dank für eure Mühen!

Ich werde euch demnächt sicherlich noch öfter was fragen müssen!


----------



## eRaaaa (2. Apr 2010)

Wollte nur noch schnell anmerken (dann halt ich auch endlich den Mund/Tastatur) dass es bei 

```
if (!(((int)s.charAt(j)>=65 && (int)s.charAt(j)<=89)
```
 <= 90 heißen muss, sonst akzeptierst du das große Z nicht und der arme Zlatko darf nicht mitspielen ;>

(Man könnte das sichelrich auch noch ein wenig abkürzen ^^)


----------



## speedle (2. Apr 2010)

Und mit Jörg, Jürgen (auch wenn es doofe Namen sind, sollten sie berücksichtigt werden) hast Du Recht. Aber diese Laute sind im ASCII gar net enthalten oder?


----------



## speedle (2. Apr 2010)

eRaaaa hat gesagt.:


> Wollte nur noch schnell anmerken (dann halt ich auch endlich den Mund/Tastatur) dass es bei
> 
> ```
> if (!(((int)s.charAt(j)>=65 && (int)s.charAt(j)<=89)
> ...



Da bin ich sogar ausnahmsweise vorhin selber draufgekommen ^^
Aber hättest du auch ne Lösung mit ö, ä, etc. Mir sind vorher Namen wie Jörg, Jürgen gar net eingefallen


----------



## eRaaaa (2. Apr 2010)

speedle hat gesagt.:


> Und mit Jörg, Jürgen (auch wenn es doofe Namen sind, sollten sie berücksichtigt werden) hast Du Recht. Aber diese Laute sind im ASCII gar net enthalten oder?




```
System.out.println((char)228 +" "+(char)196); //ä Ä
	System.out.println((char)246 +" "+(char)214); //ö Ö
	System.out.println((char)252 +" "+(char)220); //ü Ü
```


----------



## speedle (2. Apr 2010)

So, abschliessend noch die eleganteste Lösung mit Regex:

```
return s.matches("[a-zA-ZäöüÄÖÜß]+");
```


----------



## speedle (2. Apr 2010)

und gleich nochmal was von mir:


```
public static boolean containsOnlyLetters(String s) {
			for (int j = 0; j < s.length(); j++)
			if (Character.isLetter(s.charAt(j)) == false)
		return false;
		return true;
}
```

Funktioniert auch astrein, mit Umlauten und Sonderzeichen 

Verdammt, weviel Zeit mich diese Methode gekostet hat.


----------

