tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
791
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    gamp gamp ist offline Mitglied Bronze
    Registriert seit
    Feb 2010
    Beiträge
    34
    Hallo alle zusammen!

    Da Regex in allen Programmiersprachen fast gleich ist, hab ich das Thread mal in Coders Talk eröffnet, ich hoff das ist kein Problem, ansonsten bitte nach Java verschieben.

    Ich benötige einen Regex der folgendes macht:

    Here-11111-Is_Some_Weird_Stuff-Not-interesting_me-1111-ALLOWED
    Here-11111-Is_-Some_Weird_Stuff-Not-interesting_me-1111-FORBIDDEN

    Wenn der String auf -ALLOWED endet, soll er nicht matchen. Wenn der String jedoch auf -FORBIDDEN endet, soll er matchen und FORBIDDEN als Group 1 zurückgeben.

    Mein Regex:
    Code :
    1
    
    -(?!ALLOWED|ALLOWED2)((?>[^-]+))$
    Gibt nur bei <STRING>-<IRGENDWAS> "IRGENDWAS" in Group 1 zurück, wenn <IRGENDWAS> nicht "ALLOWED" oder "ALLOWED2" ist. Habs auf http://www.regexplanet.com/simple/index.html und http://www.rubular.com/r/6UUh3yimSb getested, funktioniert bei beiden prima. Jedoch wenn ich es in Java so implementiere:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    
    public class Test {
        
        static String str = "Here-11111-Is_-Some_Weird_Stuff-Not-interesting_me-1111-FORBIDDEN";
            //static String str = "Here-11111-Is_-Some_Weird_Stuff-Not-interesting_me-1111-ALLOWED"
        static String regex = "-(?!ALLOWED|ALLOWED2)((?>[^-]+))$";
        
        public static void main(String... args) throws IOException {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(str);
            if(m.matches()) {
                System.out.println("group: "+m.group(1));
            } else {
                System.out.println("nope");
            }
        }
    }
    Matcht er irgendwie garnicht, weder "ALLOWED" noch "FORBIDDEN". Ich seh allerdings den Grund nicht, sind ja keine Chars drin die ich Escapen müsste? Hat jemand ne Idee worans liegt?

    Mfg
     

  2. #2
    Avatar von Raubkopierer
    Raubkopierer Raubkopierer ist offline Mitglied Diamant
    Registriert seit
    Feb 2007
    Ort
    Saultitz (Sachsen)
    Beiträge
    1.700
    Blog-Einträge
    7
    Wenn er allowed nicht matchen soll und du dich somit nicht dafür interessierst? Warum zu Hölle packst du es dann mit in den Regex?

    Also ganz generell ist der regex erstmal schlecht strukturiert und für den Verwendungszweck unpassend. Es könnte daran liegen, dass du mit ^ arbeitest was begin of line symbolisiert aber mit dem regex dann später nicht mehrzeilig matchst und das ganze dann nicht passt etc. Außerdem ist begin of line etwas anderes als eine Newline.

    Der Grund warum es FORBIDDEN und auch nichts anderes in Group1 erscheint weil der regex wenn er matcht nur den - am Anfang konsumiert. Das ist eine Eigenschaft von negierten Gruppen, dass sie das folgende nicht einfassen, damit man was anderes damit machen kann. Und rein logisch kann die Engine damit ja auch nichts machen weil es eben nicht matcht.

    Also müsstest du deinen Regex wohl so ändern:

    Code :
    1
    
    -(FORBIDDEN)

    Die Negation von Allowed ist eigentlch wirklich unnötig, da ja an genau der Stelle wo allowed nicht stehen soll forbidden steht. Eins geht nur. Wenn du nun natürlich mehr als den einen Fall hast und alles außer allowed matchen willst musst du forbidden negieren und dann entsprechend alles andere matchen durch eine andere Gruppe.

    Achja: Und da du nun nichts wirklich unbestimmtes mehr suchst würde auch nen einfaches find ohne regex Engine genügen. Das dürfte etwas schneller gehn.
     
    Albert Einstein sagte einmal:
    Es gibt 2 Dinge die unendlich sind: Das Universum und die Dummheit der Menschen. Beim Ersten bin ich mir allerdings nicht ganz sicher.

    Stoppt die Vorratsdatenspeicherung!

  3. #3
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.802
    Blog-Einträge
    5
    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Also ganz generell ist der regex erstmal schlecht strukturiert und für den Verwendungszweck unpassend. Es könnte daran liegen, dass du mit ^ arbeitest was begin of line symbolisiert aber mit dem regex dann später nicht mehrzeilig matchst und das ganze dann nicht passt etc. Außerdem ist begin of line etwas anderes als eine Newline.
    In einer Zeichenklasse steht das Zirkumflex für Negation, nicht für einen Zeilenanfang.

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Achja: Und da du nun nichts wirklich unbestimmtes mehr suchst würde auch nen einfaches find ohne regex Engine genügen. Das dürfte etwas schneller gehn.
    Dass das kein Fall für einen regulären Ausdruck ist, sehe ich auch so. Allerdings würde ich eher zur Verwendung von endsWith raten.

    Grüße,
    Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  4. #4
    gamp gamp ist offline Mitglied Bronze
    Registriert seit
    Feb 2010
    Beiträge
    34
    Vorneweg: Meine Frage ist, wieso die REGEX-TESTER websites mir jeweils das richtige ausgeben, jedoch mein Java-Test-Programm nicht. Ich vermute es hat was mit Java String zu tun und ich Escape was nicht richtig?

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Wenn er allowed nicht matchen soll und du dich somit nicht dafür interessierst? Warum zu Hölle packst du es dann mit in den Regex?.
    Ganz einfach, da es 1000 Endungen -FORBIDDEN -ANYTHING gibt, die NICHT erlaubt sind, aber nur wenige (5 stueck) -BLA1 -BLA2 -BLA3 -BLA4 -BLA5 die erlaubt sind. Also wieso einen Regex gestalten bei dem ich 1000 Endungen hinzufügen muss damit ich immer "FORBIDDEN", "ANYTHING" etc. zurück bekomme? Also mach ich look-behind und schau ob er matched, wenn nicht -> OK, String erlaubt. Wenn er matcht -> FEHLER: BLA is forbidden.
    .[/QUOTE]

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Also ganz generell ist der regex erstmal schlecht strukturiert und für den Verwendungszweck unpassend. Es könnte daran liegen, dass du mit ^ arbeitest was begin of line symbolisiert aber mit dem regex dann später nicht mehrzeilig matchst und das ganze dann nicht passt etc. Außerdem ist begin of line etwas anderes als eine Newline.
    Soweit ich weiss benutze ich ^ in einer Class am Anfang, also indiziert es eine Negation der in der Character Class enthaltenen Chars, und keinen Zeilenanfang. Lieg ich da falsch? Und ich will weder "Begin of Line" noch "Newline" matchen, dass es da einen Unterschied gibt ist mir aber durchaus klar.
    Ich sehe auch nicht wieso der Regex schlecht strukturiert sein soll und für meinen Verwendungszweck unpassend ist. Kannst du mir bitte eine Beispiellösung mit besserer Performance und Strukturierung geben, die "passend" ist?

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Der Grund warum es FORBIDDEN und auch nichts anderes in Group1 erscheint weil der regex wenn er matcht nur den - am Anfang konsumiert. Das ist eine Eigenschaft von negierten Gruppen, dass sie das folgende nicht einfassen, damit man was anderes damit machen kann. Und rein logisch kann die Engine damit ja auch nichts machen weil es eben nicht matcht.
    Auf den oben angegebenen Regex-Test Websites erscheint sehr wohl "FORBIDDEN" in Group1 - exakt was ich wollte. Auch das Backtracking ist weitestgehend unterbunden, und - am Anfang wird "gestrippt". Du kannst es ja germ mal testen. Und da es matcht. macht es auch was.

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Also müsstest du deinen Regex wohl so ändern:
    Code :
    1
    
    -(FORBIDDEN)
    Eben genau das will ich nicht haben.

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Die Negation von Allowed ist eigentlch wirklich unnötig, da ja an genau der Stelle wo allowed nicht stehen soll forbidden steht. Eins geht nur. Wenn du nun natürlich mehr als den einen Fall hast und alles außer allowed matchen willst musst du forbidden negieren und dann entsprechend alles andere matchen durch eine andere Gruppe.
    vll. hab ich mich falsch oder ungenau ausgedrückt, die Test-Klasse ist - wie eigentlich unschwer zu erkennen - ein Testprogramm. In meinem eigentlichen Programm werden pro Stunde ca. 2500 verschiedene Strings gegen den Regex gematcht, wenn er matcht gibt er "FORBIDDEN -> Reason: Group1 not allowed" aus.

    Zitat Zitat von Raubkopierer Beitrag anzeigen
    Achja: Und da du nun nichts wirklich unbestimmtes mehr suchst würde auch nen einfaches find ohne regex Engine genügen. Das dürfte etwas schneller gehn
    Wie oben: TEST-KLASSE, quasi ein Dummy der aber nicht wirklich in mein Eigentliches Programm reinkommt.


    EDIT:

    Es muss als Regex gemacht werden, da der Regex von einer Config File gelesen wird. Das endsWith() in diesem Fall besser wäre ist mir auch klar. Es hat schon seinen Sinn wieso ich das benutze.
    Geändert von gamp (15.04.10 um 17:14 Uhr)
     

  5. #5
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.802
    Blog-Einträge
    5
    Zitat Zitat von gamp Beitrag anzeigen
    Vorneweg: Meine Frage ist, wieso die REGEX-TESTER websites mir jeweils das richtige ausgeben, jedoch mein Java-Test-Programm nicht. Ich vermute es hat was mit Java String zu tun und ich Escape was nicht richtig?
    Nein, du verwendest nur den Matcher falsch. Du solltest statt matches() eher find() verwenden.

    Grüße,
    Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  6. #6
    gamp gamp ist offline Mitglied Bronze
    Registriert seit
    Feb 2010
    Beiträge
    34
    Ah, vielen Dank, so hats geklappt!
     

Ähnliche Themen

  1. Java Regex/Matcher Backreference
    Von gamp im Forum Java
    Antworten: 1
    Letzter Beitrag: 18.02.10, 20:45
  2. JAVA regex Quantifizierer-Problem
    Von RalU im Forum Java Grundlagen
    Antworten: 3
    Letzter Beitrag: 06.01.10, 16:07
  3. Antworten: 5
    Letzter Beitrag: 19.06.06, 11:06
  4. Java REGEX Algorithmus
    Von tinella im Forum Java
    Antworten: 3
    Letzter Beitrag: 09.09.04, 16:53
  5. radiobutton als haken...
    Von mille im Forum CSS
    Antworten: 9
    Letzter Beitrag: 16.04.02, 14:18