Negation in regulären Ausdrücken

Status
Nicht offen für weitere Antworten.
S

stev.glasow

Gast
Huhu,
folgendes Problem:
nehmen wir an ich haben einen Text "Hallo ihr Säcke" und will nun prüfen ob er nicht das Wort 'Hallo' enthält.
Wie mache ich das?
Habe /[^hallo]/ probiert, was aber nicht geht, da bei diesem Ausdruck die Reihenfolge der Buchstaben keine Rolle spielt. Sprich sowohl "Hallo ihr Säcke" als auch "Holla ihr Säcke" würden false ergeben.
Natürlich könnte ich das jetzt ganz einfach lösen in dem ich den Ausdrück /hallo/ nehmen und in der if-Abfrage ein ! vor die Methode setzen würde. Das bringt mir aber nichts, da die Negation nur ein Teil eines Audruckes ist.
Jemand ne Lösung parat?
 

foobar

Top Contributor
Probier es mal so:
Code:
/(?:^hallo)/

Mit (?:) kannst du Gruppierungen anlegen die keine Auswirkungen auf Backreferences haben. Ich weiß aber nicht genau, wie man diese Gruppierung dann negiert.
 

Manfred

Bekanntes Mitglied
Rein interessehalber würde mich interessieren, was diese Ausdrücke im Detail bedeuten, hab sowas noch nie gesehen!?
 
S

stev.glasow

Gast
Manfred hat gesagt.:
Rein interessehalber würde mich interessieren, was diese Ausdrücke im Detail bedeuten, hab sowas noch nie gesehen!?
Oder meinst du was überhaupt reguläre Ausdrücke sind?
 
S

stev.glasow

Gast
Hab jetzt doch noch Probleme mit dem Ausdruck. Mit dem Text
"Hallo stev glasow, Hallo stev du"
und dem Ausdruck:
/^([^(?:stev)]*)(stev.*)/
funktioniert es so wie es soll : Die erste Gruppe entspricht "Hallo " und die zweite dem Rest des Textes.
Aber mit dem Text
"Hallo ulla glasow, Hallo ulla du"
und dem Ausdruck
/^([^(?:ulla)]*)(ulla.*)/
liefert mir die Methode false.
Ich habe dann mal alle u l a in dem Text durch x ersetzt: sprich so: "Hxxxo ulla gxxsow, Hallo ulla dx"
und auf einmal ging es. Also geht es anscheint nur wenn die Buchstaben, die in dem Ausdruck [^(?:foo)]* vorkommen, nicht anderweitig in dem Text vorkommen. Nur kann ich das so überhaupt nicht gebrauchen.
Jemand ne Idee was ich falsch mache? Is klar was ich meine?
 

Wildcard

Top Contributor
Kann sein das ich dich jetzt falsch verstehe, aber kannst du nicht einfach "(ulla)" als RegEx benutzen, einmal
Code:
matcher.lookingAt()
benutzen, und den String dann aufteilen?
 
S

stev.glasow

Gast
Ne das hilft nicht weiter, der Satz war auch nur ein Beispiel. Dass man das anderes lösen kann, war mir klar - es geht nur um die Negation eines Wortes.
[edit]
anderes Beispiel bei der deine Lösung nicht gegehen würde: /^([^(?:peter)]*)(stev.*)/
 

Wildcard

Top Contributor
Du wirst die Special constructs mit dem ? verwenden müssen.
Zum Beispiel würde
Code:
(.*)(?=stev)(.*)(ulla.*)
bei
hallo stev! das ist ulla.
folgendes ergebnis liefern:
group(1) = hallo
group(2) = stev! das ist
group(3) = ulla.

(?=stev) steht für einen positiven lookahead der 1. Gruppe wobei stev nicht gecaptured wird.
Kannst du mal einen komplizierteres Beispiel posten und genau angeben was dann rauskommen soll?
Dann versuch ich mal mein Glück.
 
S

stev.glasow

Gast
Was ist den 'lookahead' ?

Das Beispiel

Text1:
"Stev der Bursche ist nicht immer bei der Sache"
Text2:
"Stev der Idiot ist nicht immer bei der Sache"
Text3:
"Stev der Idiot ist nicht immer bei der Sache, Stev der Held ist nicht immer bei der Sache"
Text4:
"Stev der Bursche ist nicht immer bei der Sache, Stev der Bursche ist nicht immer bei Mutti"

Ergebnis bei Text 1:
Gruppe1: Stev der Bursche
Gruppe2: ist nicht immer bei der Sache

Ergebnis bei Text 2:
false, sprich er matcht erst gar nicht

Ergebnis bei Text 3:
Gruppe1: Stev der Idiot ist nicht immer bei der Sache, Stev der Bursche
Gruppe2: ist nicht immer bei der Sache


Ergebnis bei Text 4:
Gruppe1: Stev der Bursche
Gruppe2: ist nicht immer bei der Sache, Stev der Bursche ist nicht immer bei Mutti

also der Ausdruck würde dann irgendwie so aussehen
/(.*Stev.*[NOT Idiot]*.*)(ist.*)/

hof mal ich hab da jetzt keine Denkfehler drin.
[edit]

und noch was, das .* gleich am anfang in dem Audruck hätte zur folge das bei Text 4 folgende Gruppen entstehen würden:
Gruppe1: Stev der Bursche ist nicht immer bei der Sache, Stev der Bursche
Gruppe2: ist nicht immer bei Mutti
Was ich nicht möchte - er soll die erste Übereinstimmung 'finden'.
Hoffentlich ist klar was ich will.
 

Wildcard

Top Contributor
Dieses Pattern matched wenn irgendwann nach "Stev" "ist" kommt, und matched nicht
wenn dazwischen noch ein "Idiot" steht. Das ist zwar immer noch nicht ganz das was du suchst,
aber vieleicht nützt es dir ja trotzdem was. Wenn mir was besseres einfällt meld ich mich.
Code:
((.*Stev)(?!.*Idiot)(.*))(ist.*)
Die gesplitteten Strings sind in group(1) und group(4).

zur erklärung:
(.*Stev) matched nur wenn (.*Idiot) nicht matched (negativer lookahead ?!).
(?.*!Idiot) ist keine Capturing group, und gehört auch nicht zur (.*Stev) gruppe. Es wird einfach
"vergessen" und der nächsten gruppe zur verfügung gestellt. daher non-capturing
 

Wildcard

Top Contributor
um den 4. Fall in den griff zu kriegen könnte man in diese Richtung gehen:
Code:
       Pattern pat = Pattern.compile("((.*Stev)(?!.*Idiot)(.*))(ist.*)");
        Matcher mat = pat.matcher("Stev der Bursche ist nicht immer bei der Sache, Stev der Bursche ist nicht immer bei Mutti");
        while (mat.lookingAt())
        {
            System.out.println(mat.group(1));
            System.out.println(mat.group(4));
            mat = pat.matcher(mat.group(1));
        }

Vieleicht hat ja jemand eine bessere Idee.
 
S

stev.glasow

Gast
OK, danke erst mal, guck mir das heute Abend mal an, meld mich dann.
 

foobar

Top Contributor
Was ist den 'lookahead' ?
Ein Lookahead kann auf die Daten zugreifen, auf die in diesem Pattern gar nicht gematched wird. Das funktioniert in beide Richtungen. Das bedeudetet du kannst gucken was nach oder vor dem gematchten Pattern passiert, ohne die Capturing-Groups zu beeinflussen.
 
S

stev.glasow

Gast
Ok, thx, mit /(.*Stev(?!.*Idiot).*)(ist.*)/ geht es jetzt. Bis auf das Problem mit dem 4ten text. Dort liefert er mir das so wie angesprochen, mal schaun
 

Wildcard

Top Contributor
Wildcard hat gesagt.:
um den 4. Fall in den griff zu kriegen könnte man in diese Richtung gehen:
Code:
        Pattern pat = Pattern.compile("((.*Stev)(?!.*Idiot)(.*))(ist.*)"); 
        Matcher mat = pat.matcher("Stev der Bursche ist nicht immer bei der Sache, Stev der Bursche ist nicht immer bei Mutti"); 
        while (mat.lookingAt()) 
        { 
            System.out.println(mat.group(1)); 
            System.out.println(mat.group(4)); 
            mat = pat.matcher(mat.group(1)); 
        }

Wie gesagt, wenn du es so machst kommst du auf den ersten Treffer. Leider musst dir dir denn String dann noch
zusammenbauen da eben Teile abgeschnitten werden. Ist zwar nur ein workaround, aber ein bessere Idee hab ich zur Zeit auch nicht.
 
S

stev.glasow

Gast
Jo, wäre eine Möglichkeit, arbeite nur gar nicht mit Java :?
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben