zukzuk Geschrieben 26. August 2016 Geschrieben 26. August 2016 (bearbeitet) 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 26. August 2016 von zukzuk Zitieren
zukzuk Geschrieben 26. August 2016 Autor Geschrieben 26. August 2016 (bearbeitet) 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 26. August 2016 von zukzuk Zitieren
Whiz-zarD Geschrieben 26. August 2016 Geschrieben 26. August 2016 (bearbeitet) 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 26. August 2016 von Whiz-zarD Zitieren
zukzuk Geschrieben 26. August 2016 Autor Geschrieben 26. August 2016 (bearbeitet) 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 26. August 2016 von zukzuk Zitieren
stefan.macke Geschrieben 26. August 2016 Geschrieben 26. August 2016 (bearbeitet) . 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 26. August 2016 von stefan.macke Zitieren
zukzuk Geschrieben 26. August 2016 Autor Geschrieben 26. August 2016 (bearbeitet) 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 26. August 2016 von zukzuk Zitieren
Whiz-zarD Geschrieben 26. August 2016 Geschrieben 26. August 2016 (bearbeitet) 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 26. August 2016 von Whiz-zarD Zitieren
zukzuk Geschrieben 26. August 2016 Autor Geschrieben 26. August 2016 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. Zitieren
stefan.macke Geschrieben 27. August 2016 Geschrieben 27. August 2016 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. Zitieren
zukzuk Geschrieben 27. August 2016 Autor Geschrieben 27. August 2016 Ist dann halt wohl ein Fall von "is' halt so, weil's in Java eben so is'". Danke, zukzuk Zitieren
Empfohlene Beiträge
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.