# String nach Zahlen durchsuchen



## MrClave (6. Okt 2012)

Moin,

Ich würde gerne einen String (Benutzer Name) nach Zahlen und Sonderzeichen durchsuchen und falls der String diese enthält, soll das Programm stoppen und per JOptionPane eine Error Message ausgeben.
Ich habe bereits alles, bis auf die Suche nach den Zahlen. 
Ich habe bereits gegooglet, allerdings werde ich daraus nicht schlauer.

Codeschnippsel:

```
String userName = JOptionPane.showInputDialog("Insert your full Name.", "Ex. Peter Petersen");
		if( userName.equals("") )
		{
			JOptionPane.showMessageDialog(null, "Name required", "Please enter your Name.", JOptionPane.ERROR_MESSAGE);
			return;
			
		}
```

Das erste if soll gucken, ob der User überhaupt einen Namen eingegeben hat. 
Gäbe es da eine andere Variante, die besser aussieht, als diese hier ? 
Ich habe es mit userName != null versucht, allerdings funktioniert dies nicht.

Und wie genau soll ich die Suche nach den Sonderzeichen und Zahlen anstellen ?
Soll ich ein array mit diversen Zeichen / Zahlen definieren oder gibt es da leichtere Wege ?
Und falls ich ein array benutzen soll/kann, mit welcher Methode wende ich diesen dann an ?
.matches() / .contains() / o.Ä. ?

Und bei der Error Message kommt plötzlich nur noch der Text "Name required". 
Vor ein paar Minuten stand allerdings noch der Text "Please enter your Name." da drunter. 
Wo liegt der Fehler so plötzlich ?

Und bitte kein mega Fach-Chinesisch, ich bin noch Anfänger, und versuche mich gerade an etwas (für mich) schwierigeren Dingen.

Danke im Voraus.


----------



## insane80 (6. Okt 2012)

Hallo.

Das ist schon richtig mit der if-Abfrage, denn ich glaube, dass wenn nichts eingegeben wird, auch ein Leer-String zurückgegeben wird und nicht null. 
	
	
	
	





```
userName.isEmpty()
```
 würde auch gehen.

Um zu schauen, ob ein String Zahlen enthält könntest du Regular Expressions nutzen. 
Zum Beispiel:


```
String bla = "xyz1111b111";
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(bla);
        if (matcher.find()) {
           //do something
        }
```


----------



## Nachtschatten (6. Okt 2012)

Schau dir mal die Regulären Ausdrücke auf Wikipedia an. Ich fand die Übersicht da sehr hilfreich.
Mit Regulären Ausdrücken kannst du Prüfen ob etwas der gewollten Form entspricht.
Z.B. [A-Z] müsste ein Großbuchstabe sein. [a-z] für die Kleinbuchstaben.
Des Weiteren gibt es noch {min,max} für die Angabe wie oft ein Zeichen das in [] wie weit  vorkommen darf.  
[A-Z]{1} würde bedeuten das ein Großbuchstabe stehen muss.
[a-z]{2,} würde bedeuten das Mindestens zwei Kleinbuchstaben vorkommen müssen.
[A-Z]{1}[a-z]{2,} Würde für Kai ebenso Passen wie für Herbert.  Ein Petra Musterfrau ginge nicht da zum einen ein Leerzeichen und mehr als ein Großbuchstabe darin vorkommen.

Für Petra Musterfau wäre es
(^[A-Z]{1}[a-z]{1,}[ ]{1}[A-Z]{1}[a-z]{1,}$)


```
String regex = "(^[A-Z]{1}[a-z]{1,}[ ]{1}[A-Z]{1}[a-z]{1,}$)";
		
		if (strDeineTextfeldeingabe.matches (regex))
		{
//			Mach was
		} //	if (strDeineTextfeldeingabe.matches (regex))
```

Deinen Regulären Ausdruck kannst du online z.B. auf regexe - Reguläre Ausdrücke online testen überprüfen.


----------



## MrClave (6. Okt 2012)

Danke für die Antworten. 
Leider bekomme ich nur noch Fehler, wenn ich regex benutze. Ich habe es schon importiert, sofern dies überhaupt von Nöten ist, aber nichts hilft.


```
String regex = "(^[A-Z]{1}[a-z]{+}[ ]{+}[A-Z]{1}[a-z]{+}[:punct:]$)";
		
		String userName = JOptionPane.showInputDialog("Insert your full Name.", "Ex. Peter Petersen");
		
		if( userName.isEmpty() )
		{
			JOptionPane.showMessageDialog(null, "Name required", "Please enter your Name", JOptionPane.ERROR_MESSAGE);
			return;
			
		} else if( userName.matches(regex)){
			
			JOptionPane.showMessageDialog(null, "Name required", "Please enter your Name", JOptionPane.ERROR_MESSAGE);
			return;
		}
```


```
Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 14
(^[A-Z]{1}[a-z]{+}[ ]{+}[A-Z]{1}[a-z]{+}[:punct:]$)
              ^
	at java.util.regex.Pattern.error(Unknown Source)
	at java.util.regex.Pattern.closure(Unknown Source)
	at java.util.regex.Pattern.sequence(Unknown Source)
	at java.util.regex.Pattern.expr(Unknown Source)
	at java.util.regex.Pattern.group0(Unknown Source)
	at java.util.regex.Pattern.sequence(Unknown Source)
	at java.util.regex.Pattern.expr(Unknown Source)
	at java.util.regex.Pattern.compile(Unknown Source)
	at java.util.regex.Pattern.<init>(Unknown Source)
	at java.util.regex.Pattern.compile(Unknown Source)
	at java.util.regex.Pattern.matches(Unknown Source)
	at java.lang.String.matches(Unknown Source)
	at WeightTax.main(WeightTax.java:27)
```

Ich habe auch schon nur mit [A-Z], aber da reagiert er gar nicht drauf.
Was mache ich falsch ?

Und dann nochmal :
Wieso bekomme ich bei der Error Message bei leerem String 

```
JOptionPane.showMessageDialog(null, "Name required", "Please enter your Name", JOptionPane.ERROR_MESSAGE);
```
nur noch *Name required* als Message und kein *Please enter your Name* angezeigt ?
Er hat es vorher getan, nur auf einmal kommt der zweite Text nicht mehr mit.


----------



## Nachtschatten (6. Okt 2012)

Dein regulärer Ausdruck ist nicht ganz koscha. Probiere den wie gesagt online. Und las erstmal die "Sonderzeichen wie {+} weg und nim dafür das {1,}. Da hatte ich am Anfang auch Probleme.


```
public class regextest
{
	public static void main (String [] args)
	{
		new regextest ();
	} //	main

	// Regex
	private String strRegex = "(^[A-Z]{1}[a-z]{1,}[ ]{1}[A-Z]{1}[a-z]{1,}$)";
	private String strRegex2 = "(^[A-Z]{1}[a-z]{1,}[ ]{1,}[A-Z]{1}[a-z]{1,}.$)";
	
	//	Eingabe
	private String strEingabe = "Petra Musterfrau";
	private String strEingabe2 = "Peter Petersen.";
	
	public regextest()
	{
        if (strEingabe.matches (strRegex))
        {
          System.out.println ("Passt !");
        } //    if (strEingabe.matches (strRegex))
        
        if (strEingabe2.matches (strRegex2))
        {
        	System.out.println ("Passt schon wieder !");
        }	//	 if (strEingabe2.matches (strRegex2))
	} //	constructor
} //	class
```

Geht. Aber wenn ich das Richtig Verstanden habe möchtest du ja vor dem Vornamen das Ex. oder sowas wie Dr., Prof...... In dem Fall müsstest du den regulären Ausdruck noch etwas umbauen.


----------



## Bernd Hohmann (6. Okt 2012)

Nachtschatten hat gesagt.:


> Dein regulärer Ausdruck ist nicht ganz koscha.



Regex enthält immer irgendwelche Schweinereien und ist daher niemals kosher zu bekommen.

Bernd


----------



## MrClave (6. Okt 2012)

Danke dir!
Ich hab' meinen Fehler jetzt verstanden.
Ich habe als Input meinen Namen eingegeben, welcher 'ü' enthält. Das akzeptiert der natürlich nicht ohne weiteres.
Und die if-Abfrage ist auch verkehrt, da ich so, wie sie da steht, eine Fehlermeldung bekomme, wenn ich den Namen richtig eintippe.

```
else if(!userName.matches(regex)){
			JOptionPane.showMessageDialog(null, "Please enter your Name", "Wrong Name", JOptionPane.ERROR_MESSAGE);
			return;
		}
```

So benötige ich es in meinem Programm.
Mein ERROR_MESSAGE Problem habe ich so eben auch gelöst! Hab' die Titel und Message Parameter vertauscht!


----------



## MrClave (7. Okt 2012)

Okay, sorry für's spammen, aber ein Problem habe ich da wieder mal.
Wie Prüfe ich meinen String richtig auf Sonderzeichen ? 
	
	
	
	





```
! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~
```
Mit der unten stehenden Methode funktioniert dies nämlich nicht. Egal ich ob 1, 2 oder tausend Sonderzeichen eingebe. 
Zahlen hingegen funktionieren wunderbar und der Rest auch. 


```
// ------------------------------------------ Regular Expressions ------------------------------------------ \\
		
		String regexNaming = "(^[A-Z]{1}[a-z]{1,}[ ]{1}[A-Z]{1}[a-z]{1,}$)";
		String regexNumbers = "(^[0-9]{1,10}[.]{0,1}[0-9]{0,2}$)";
		String regexSpecialSigns = "(^[:punct:]{0,}$)";
		String regexNumerals = "(^[0-9]{0,}$)";
		
		// ------------------------------------------ Testing User Name ------------------------------------------ \\
		
		String userName = JOptionPane.showInputDialog("Insert your full Name.", "Example: Peter Petersen");
		
		if( userName.isEmpty() ){
			JOptionPane.showMessageDialog(null, "Please enter your Name.", "NO_INPUT_EXCEPTION", JOptionPane.ERROR_MESSAGE);
			return;
			
		} else if( !userName.matches(regexNaming) ) {
			JOptionPane.showMessageDialog(null, "Please enter your Name in the correct way.", "MISMATCH_EXCEPTION", JOptionPane.ERROR_MESSAGE);
            return;
            
        } else if( userName.matches(regexSpecialSigns) || userName.matches(regexNumerals) ) {
			JOptionPane.showMessageDialog(null, "Names should not contain numbers or special Signs.", "NUMBER_EXCEPTION", JOptionPane.ERROR_MESSAGE);
			return;
				
		}
```


----------



## hüteüberhüte (7. Okt 2012)

Wie wärs damit:

```
if (str.contains("\\W")) {
  // enthält Sonderzeichen
} else {
  // enthält keine Sonderzeichen
}
```


----------



## faetzminator (7. Okt 2012)

MrClave, [c][A-Z]{1}[/c] -> [c][A-Z][/c], [c][a-z]{1,}[/c] -> [c][a-z]+[/c], [c][ ]{1}[/c] -> [c] [/c], ...
[c](^[A-Z]{1}[a-z]{1,}[ ]{1}[A-Z]{1}[a-z]{1,}$)[/c] -> [c]^[A-Z][a-z]+ [A-Z][a-z]+$[/c]


----------



## MrClave (7. Okt 2012)

@hüteüberhüte
Ich würde das gerne in einen der obigen Strings packen, da ich so angefangen habe und ungern mittendrin den Stil wechsle. Heißt natürlich, sofern ich eine Lösung nach meinen Wünschen überhaupt noch finden werde 
Ansonsten danke für den Vorschlag!

@faetzminator
Da das das erste Mal ist, dass ich mit regex arbeite, wird da noch viel überflüssiges Zeug rumschwirren.
Ich werd's vielleicht ändern, aber mir ist grad erstmal wichtig, dass ich die Logik und Zusammensetzung mit meinen if-Abfragen dabei verstehe.
Es ist ohnehin ein Thema, welches wir in der Schule später näher durchgehen werden. :rtfm:

Mir ist grad nur wichtig, dass ich das Programm richtig zum laufen bringe, was leider gerade an den Sonderzeichen hapert.


----------



## hüteüberhüte (7. Okt 2012)

Geheimtipp: Predefined Character Classes (The Java™ Tutorials > Essential Classes > Regular Expressions)

Es gibt aber durchaus Namen, in denen Sonderzeichen vorkommen, oder die mehr als zwei Bestandteile haben. Was soll damit geschehen?


----------



## faetzminator (7. Okt 2012)

MrClave hat gesagt.:


> Da das das erste Mal ist, dass ich mit regex arbeite, wird da noch viel überflüssiges Zeug rumschwirren.


Es ist ganz einfach  statt [c]{1}[/c] brauchst du nichts zu schreiben, statt [c]{0,}[/c] einfach [c]*[/c], [c]{1,}[/c] -> [c]+[/c], [c]{0,1}[/c] -> [c]?[/c]. Und einzelne Buchstaben wie [c][a][/c] muss man natürlich nicht in eine Gruppierung stecken. Einfach [c]a[/c] 
Ist aber alles auch sehr schön in der Javadoc erklärt: [japi]Pattern[/japi]


----------



## MrClave (7. Okt 2012)

Was für Namen haben denn Sonderzeichen ? 
Also ich kenne niemanden, der &(%&"% &(%&§%" heißt. :noe:
Zweitnamen sollen eigentlich nicht mit rein genommen werden. Lediglich der Vor- und Nachname.
Falls doch, soll das Programm sie einfach mit rein nehmen. Ist irrelevant für diesem Fall.

Aber um das zu Bewerkstelligen, werde ich wohl wieder meine regex Einträge abändern müssen, so viel Glück wie ich habe 

@faetzminator
Ok, ich werde es dann zukünftig mal versuchen mit den shortcuts 


Hätte vielleicht jemand Lust, mir einen Ansatzpunkt zu liefern, wie ich jetzt am besten die obigen Probleme am besten löse ?
Ich werd's auch nicht copy-pasten, da ich ohnehin noch 3 weitere if-Abfragen danach abdecken muss


----------



## Bernd Hohmann (7. Okt 2012)

MrClave hat gesagt.:


> Was für Namen haben denn Sonderzeichen ?
> Also ich kenne niemanden, der &(%&"% &(%&§%" heißt. :noe:



Zb. die Firma "Irgendwas Gmbh & Co.KG" hat mindestens ein & drin ("Eine Firma ist der Name, unter dem ein Kaufmann seine Geschäfte betreibt").

Lass das mit den RegEx, das ist write-only und immer schwer nachträglich anzupassen.

Bau Dir einfach einen kleinen Filter, der nur die erlaubten Zeichen durchlässt.


```
public class NamenFilter {

	final static String ASC_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜß";
	final static String ASC_LOWER = "abcdefghijklmnopqrstuvwxyzäöüß";
	final static String ASC_NUMBER = "0123456789";
	final static String NAMETEST = ASC_UPPER + ASC_LOWER + ASC_NUMBER + " .-+&";

	public static void main(String[] args) {

		//String strInput = "Professor Doktor Müller-Lüdenscheid";
		String strInput = "Firma Kokolores @ Unbrauchbar GmbH & Co.KG";

		StringBuilder strb = new StringBuilder();

		for (int i = 0; i < strInput.length(); i++) {
			char ch = strInput.charAt(i);
			if (NAMETEST.indexOf(ch) != -1) {
				strb.append(ch);
			}
		}

		System.out.println("Bereinigt: " + strb.toString());

	}
}
```


----------



## MrClave (7. Okt 2012)

Ok, mein Fehler. Hätte wohl die Aufgabe etwas genauer beschreiben sollen, damit diese Missverständnisse  mit den Namen nicht aufkommen.
Mein Programm errechnet den BMI einer Person, worauf dann anschließend eine Steuer festgelegt wird, je nach Ergebnis des BMI.
Untergewicht (200DKK), Normal(400DKK), Übergewicht(3000DKK) & Fett(6000DKK)
Die jeweilige Steuer darf aber nicht mehr wie 10% des Einkommens betragen. Tut sie dies, wird das maximum (Also die 10% des Einkommens) angerechnet. 
Für das Programm muss der Nutzer (*NUR* ein Personenname) seinen Namen, sein Gewicht, seine Größe und sein Einkommen eingeben.

Mit RegEx habe ich bereits die Numerischen inputs gefiltert, nur das mit dem Namen und den Sonderzeichen will nicht klappen. Auf Zahlen hab' ich es aber schon erfolgreich geprüft.

Ich würde auch gerne bei RegEx bleiben, da ich nun schon alles drauf abgestimmt habe und ich dies auch gern' lernen würde. :toll:
Denn mit der Zeit werd' ich ja sehen, worauf ich alles achten muss dabei


----------



## hüteüberhüte (7. Okt 2012)

Du willst doch nicht sagen, daß Namen nur aus A-Z, a-z und einem Leerzeichen bestehen, und daß alle anderen Zeichen quasi Sonderzeichen sind..

Gesendet mit Tapatalk 2


----------



## MrClave (7. Okt 2012)

hüteüberhüte hat gesagt.:


> Du willst doch nicht sagen, daß Namen nur aus A-Z, a-z und einem Leerzeichen bestehen, und daß alle anderen Zeichen quasi Sonderzeichen sind..
> 
> Gesendet mit Tapatalk 2



Hat wer gesagt ? ???:L

Die Punct Methode enthält diese Zeichen: 
	
	
	
	





```
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
```
Und was ich prüfen will sind diese Sonderzeichen und Zahlen im Namen.
Das richtige Format (Peter Petersen) wäre zwar auch nicht schlecht, aber ist für den Anfang dann vielleicht doch etwas viel.

Es sollte im besten Falle Vor- und Nachname enthalten, jedoch reicht auch nur der Vorname. (Zweitnamen sind erst mal egal)

Es geht hier letzt endlich nur um eine Übung, und kein perfektes Programm.


----------



## MrClave (8. Okt 2012)

So langsam verzweifel ich!
Jetzt will der nicht mal mehr die Numerischen inputs kontrollieren.
Hab' zwar die gesamte ASCII Tabelle nun definiert, und trotzdem will der das nicht annehmen. Selbst, wenn ich die Punctuations davon subtrahiere.

Mein Ansatz ist irgendwie komplett falsch -.-
Im Code sind 2 von 5 Fälle, die ich gerne überprüfen möchte.
Und ich will nicht die Zeichen rausfiltern, sondern sie erkennen und dann eine dementsprechende Fehlermeldung ausgeben.
Das kann doch nicht unmöglich sein ???:L


```
// ------------------------------------------ Regular Expressions ------------------------------------------ \\
		
		final String REGEX_NUMERALS = "(^[\\d]$)";
		final String REGEX_LITERALS = "(^\\x00-\\x7F$)";
		final String REGEX_SPECIAL_SIGNS = "(^\\p{Punct}$)";
		
		// ------------------------------------------ Testing User Name ------------------------------------------ \\
		
		String userName = JOptionPane.showInputDialog("Insert your full Name.", "Example: Peter Petersen");
		
		if( userName.isEmpty() ){
			JOptionPane.showMessageDialog(null, "Please enter your Name.", "NO_INPUT_EXCEPTION", JOptionPane.ERROR_MESSAGE);
			return;
			
		} else if( userName.contains(REGEX_SPECIAL_SIGNS) || userName.contains(REGEX_NUMERALS)  ) {
			JOptionPane.showMessageDialog(null, "Names should not contain numbers or punctuation.", "MISMATCH_EXCEPTION", JOptionPane.WARNING_MESSAGE);
            return;
            
        } 
		
		// ------------------------------------------ Testing User Income ------------------------------------------ \\
		
		String userIncome = JOptionPane.showInputDialog("Insert your income in DKK.\nPlease seperate with a dot.", "< Example: 12345.67 >");
		 
		if( userIncome.isEmpty() ){
			JOptionPane.showMessageDialog(null, "Please enter your income.", "NO_INPUT_EXCEPTION", JOptionPane.ERROR_MESSAGE);
			return;
			
		} else if( userIncome.contains(REGEX_LITERALS) ){
			JOptionPane.showMessageDialog(null, "Numbers should not contain literals.", "MISMATCH_EXCEPTION", JOptionPane.WARNING_MESSAGE);
            return;
            
		} else if( Double.parseDouble(userIncome) <= UNDERWEIGHT_TAX ){
			JOptionPane.showMessageDialog(null, "Your income must at least be over 200 DKK.", "LOW_INPUT_EXCEPTION", JOptionPane.WARNING_MESSAGE);
			return;
			
		} else if( Double.parseDouble(userIncome) >= LOGICAL_MONEY_LIMIT ){
			JOptionPane.showMessageDialog(null, "The number you entered is to high.", "HIGH_INPUT_EXCEPTION", JOptionPane.WARNING_MESSAGE);
			return;
			
		}
```


----------



## faetzminator (8. Okt 2012)

[c]contains()[/c] verwendet keine Regex. Verwende [c]matches()[/c] und als Regex statt [c]"(^[\\d]$)"[/c] einfach [c]".*[\\d].*"[/c] oder - falls gewünscht - mit [japi]Pattern[/japi] und [japi]Matcher[/japi].


----------



## MrClave (8. Okt 2012)

faetzminator hat gesagt.:


> [c]contains()[/c] verwendet keine Regex. Verwende [c]matches()[/c] und als Regex statt [c]"(^[\\d]$)"[/c] einfach [c]".*[\\d].*"[/c] oder - falls gewünscht - mit [japi]Pattern[/japi] und [japi]Matcher[/japi].



Verflixt noch mal -.-
Hab' heute in der Schule damit rumgespielt, und tatsächlich funktioniert es *BIS JETZT* mit 
	
	
	
	





```
.matches()
```
Kein Wunder, dass es mit 
	
	
	
	





```
.contains()
```
 nicht funktionierte <.>
Hab's zwar bestimmt nicht 100% korrekt und universell anwendbar gelöst, dennoch ein kleines Erfolgserlebnis 

Falls nicht wieder irgendwelche Probleme auftreten, schon mal DANKE an dich faetzminator!


----------



## hüteüberhüte (8. Okt 2012)

Hier einfach mal mit Pattern und Matcher:

```
package javaforum;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author hüte
 */
public class Namen {

    private static final Pattern pat =
            Pattern.compile("^([A-ZÄÖÜ][a-zäöüß]+)\\s+([A-ZÄÖÜ][a-zäöüß]+)$");

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        for (;;) {
            System.out.print("Name eingeben: ");
            String line = br.readLine();
            Matcher m = pat.matcher(line);
            if (m.find()) {
                System.out.print("Vorname: ");
                System.out.print(m.group(1));
                System.out.print(", Zuname: ");
                System.out.print(m.group(2));
                System.out.print(", Name korrekt!");
            } else {
                System.out.print("Eingabe: ");
                System.out.print(line);
                System.out.print(", Name inkorrekt");
            }
            System.out.println();
        }
    }
}
```
Evtl. wäre \p{Alpha} oder \p{Punct} bzw. [^\p{Punct}] auch passig


----------

