Zum Inhalt springen

Regex-Frage zu Java


zukzuk

Empfohlene Beiträge

Hallo,

ich habe folgende Frage zu Regexen in Java.

Das Problem ist, dass mein Regex-Match immer fehlschlägt (= false):

        String str = ".*";
        if (result.matches(str)) {
            JOptionPane.showMessageDialog(null, "gebe Falsch zurück (Regex matcht!)", "Test", JOptionPane.OK_CANCEL_OPTION);
            return false;
        } else {
            JOptionPane.showMessageDialog(null, "gebe Richtig zurück (Regex matcht nicht!)", "Test", JOptionPane.OK_CANCEL_OPTION);
            return true;
        }

 

Ein trivialer Match mit "Fooo".matches(".*") funktioniert dagegen.

Evtl. ist das ein Unicode-Problem, da in dem String "kaputte" Umlaute auftauchen? (umgebender Code s. u.).

 

Danke für jede Hilfe.

zukzuk

 

Mein umgebender Code:

    private boolean pmtu_success(String ip, int size) throws IOException {
        boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");
        ProcessBuilder processBuilder;
        if (isWindows) {
            processBuilder = new ProcessBuilder("ping", "-f", "-n", "1", "-l", "" + size, ip);            
        } else {
            processBuilder = new ProcessBuilder("ping", "-c", "1", "-s", "" + size, "-M", "do" + ip);
        }
	

        Process proc;
        proc = processBuilder.start();
	        BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        StringBuilder builder = new StringBuilder();
        String line = null;
        try {
            while ( (line = reader.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty("line.separator"));
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        String result = builder.toString();
        JOptionPane.showMessageDialog(null, result, "Test", JOptionPane.OK_CANCEL_OPTION);
        
        String str = ".*";
        if (result.matches(str)) {
            JOptionPane.showMessageDialog(null, "gebe Falsch zurück (Regex matcht!)", "Test", JOptionPane.OK_CANCEL_OPTION);
            return false;
        } else {
            JOptionPane.showMessageDialog(null, "gebe Richtig zurück (Regex matcht nicht!)", "Test", JOptionPane.OK_CANCEL_OPTION);
            return true;
        }
        
    
    }
	
Bearbeitet von zukzuk
Link zu diesem Kommentar
Auf anderen Seiten teilen

Anders gefragt:

Was muss in <string> stehen, so dass

<string>.matches(".*")

false zurückliefert? (weil das passiert mir gerade :-).

Edit: Nach nochmaliger Betrachtung hat sich herausgestellt, dass <string> keinen Zeilenumbruch enthalten darf, damit dieser Regex matcht. Wie formuliere ich den Regex denn in Java so, so dass es keinen Unterschied macht, ob Zeilenumbrüche oder sonstiger Whitespace da stehen?

Ich möchte einfach, dass der Regex-Match auf ".*" matcht, egal wie viele Zeilenumbrüche in dem überprüften String stehen.

Bearbeitet von zukzuk
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Code ist auch komplett unübersichtlich. Teile es in Klassen und Methoden auf.
Das ist ja reiner Spaghetticode. Die Methode macht viel zu viel. ;)

Zu deiner Frage:
Der Ausdruck ".*" ist immer true, wenn der String nicht leer ist, da der Ausdruck bedeutet, dass beliebige Zeichen beliebig oft im String stehen dürfen. 

Die Frage ist also, was willst du damit ausdrücken?

Edit:
Interessant. Selbst bei leeren String gibt er True zurück.

 

 

Bearbeitet von Whiz-zarD
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 8 Minuten schrieb Whiz-zarD:

Dein Code ist auch komplett unübersichtlich. Teile es in Klassen und Methoden auf.
Das ist ja reiner Spaghetticode. Die Methode macht viel zu viel. ;)

Zu deiner Frage:
Der Ausdruck ".*" ist immer true, wenn der String nicht leer ist, da der Ausdruck bedeutet, dass beliebige Zeichen beliebig oft im String stehen dürfen. 

Die Frage ist also, was willst du damit ausdrücken?

Edit:
Interessant. Selbst bei leeren String gibt er True zurück.

 

 

Also von wegen Codequalität: das ist mein allererster Gehversuch in Java. Ich versuche da auch kein fertiges Produkt auszuliefern, sondern ich möchte etwas bestimmtes nachprüfen.

Dass der Regex-Match bei leerem String "True" zurück gibt, finde ich nicht so interessant, da ".*" für "beliebig viele Zeichen" steht (also auch gar keins). Was ich nicht verstehe, ist, warum er "False" zurück gibt, wenn ein Newline-Character im überprüften String enthalten ist. Also bspw. "Foo\nBar" matcht nicht auf ".*" (zumindest in Java!).

Bearbeitet von zukzuk
Link zu diesem Kommentar
Auf anderen Seiten teilen

. matcht alle Zeichen außer Zeilenumbrüche. Der Quantifizierer * steht für 0..n Zeichen. Also matcht .* Leerstrings und alle anderen, solange es sich um einzelne Zeilen handelt.

Du kannst aber den Dotall-Modus anschalten. Der macht, dass * auch Zeilenumbrüche matcht. Müsste der Schalter m sein (glaube ich). Also z.B. /.*/m In Java musst du das glaube ich aber als Option bei matches() angeben.

Edit: Hier die Syntax in Java: http://stackoverflow.com/questions/3651725/match-multiline-text-using-regular-expression

Bearbeitet von stefan.macke
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 5 Minuten schrieb stefan.macke:

. matcht alle Zeichen außer Zeilenumbrüche. Der Quantifizierer * steht für 0..n Zeichen. Also matcht .* Leerstrings und alle anderen, solange es sich um einzelne Zeilen handelt.

Du kannst aber den Multilinemodus anschalten. Der macht, dass * auch Zeilenumbrüche matcht. Müsste der Schalter m sein (glaube ich). Also z.B. /.*/m In Java musst du das glaube ich aber als Option bei matches() angeben.

Hallo stefan.macke,

was den Multilinemodus angeht: so was ähnliches hatte ich auch noch in den hintersten Ecken meines Hinterkopfes, aber ich weiß bei bestem Willen nicht mehr, wie man das dann in Java schreibt. Kurz googlen hat mir auch nicht geholfen.

Ich bin übrigens Perl-Regexen gewohnt. Da matcht ".*" selbstverständlich auf einen String mit Zeilenumbrüchen (auf die erste Zeile ;-).

Offenbar setzt Java irgendwelche "Anchors" um die Regexen, also sowas wie "\A.*\Z" bei Perl.

Jetzt muss mir nur noch jemand erklären, wie konkret man den Multiline-Modus bei Java anschaltet, dann probiere ich weiter ;-).

Bearbeitet von zukzuk
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah ja, stimmt. Ich bin kein großer Regex-Experte. * steht ja für 0..n.

Unter java kannst du reguläre Ausdrücke mit der Pattern- und Matcher-Klasse auswerten:
https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

(Ich merke schon, ich müsste mich echt mal wieder mit Java beschäftigen. Nach 5 Jahren C# hat man doch vieles von Java verlernt ^^)

Bearbeitet von Whiz-zarD
Link zu diesem Kommentar
Auf anderen Seiten teilen

Also das Problem habe ich jetzt gelöst mit:

(?s)

(Single-Line-Attribut). Damit matcht "." auch auf Newlines (soweit wie unter Perl). Ich verstehe aber nicht, warum man bei Java die gesamte Regex von vorne bis hinten deklarieren muss. (also quasi immer "^...$")) bzw. warum Java das sonst implizit macht. Denn intuitiv hätte ich erwartet, dass egal welcher String auf ".*" matcht (sofern es denn ein String ist ;-)). Und das ist bei Java eben nicht der Fall, wenn der überprüfte String Zeilenumbrüche enthält.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 10 Stunden schrieb zukzuk:

Ich verstehe aber nicht, warum man bei Java die gesamte Regex von vorne bis hinten deklarieren muss.

 

Zitat

matches tries to match the expression against the entire string and implicitly add a ^ at the start and $ at the end of your pattern, meaning it will not look for a substring.

http://stackoverflow.com/questions/4450045/difference-between-matches-and-find-in-java-regex

Und da . im "normalen" Modus keine Zeilenumbrüche matcht, ist bei einem String mit Zeilenumbruch quasi vor dem ersten Umbruch Feierabend (implizites $). Da aber danach noch Zeichen folgen, matcht der komplette Ausdruck halt nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...