# Negation in regulären Ausdrücken



## stev.glasow (15. Feb 2005)

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 (15. Feb 2005)

Probier es mal so:

```
/(?:^hallo)/
```

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


----------



## stev.glasow (15. Feb 2005)

Supi, danke


----------



## Manfred (15. Feb 2005)

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


----------



## foobar (15. Feb 2005)

Guckst du hier http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html


----------



## Student (15. Feb 2005)

Hallo,
schau mal bei Google die ersten paar Links an:
:arrow: http://www.google.de/search?hl=de&q=regular+expressions

Sind zwar englischsprachig, helfen aber ungemein weiter. ;-)

Grüße Ben ;-)


----------



## stev.glasow (15. Feb 2005)

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?


----------



## Manfred (15. Feb 2005)

Nein, das hat schon gepasst!

Reguläre Ausdrücke... hmm gültige wohl, oder!?


----------



## foobar (15. Feb 2005)

Manfred hat gesagt.:
			
		

> Nein, das hat schon gepasst!
> 
> Reguläre Ausdrücke... hmm gültige wohl, oder!?



Gibt es auch ungültige??


----------



## Manfred (16. Feb 2005)

Also zumindest nicht-Reguläre müsste es geben ;-)


----------



## stev.glasow (16. Feb 2005)

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 (16. Feb 2005)

Kann sein das ich dich jetzt falsch verstehe, aber kannst du nicht einfach "(ulla)" als RegEx benutzen, einmal 

```
matcher.lookingAt()
```
 benutzen, und den String dann aufteilen?


----------



## stev.glasow (16. Feb 2005)

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:  /^([^(?eter)]*)(stev.*)/


----------



## Wildcard (16. Feb 2005)

Ich glaube negieren geht etwa so:

```
(.*)(?!stev$)(stev.*)
```


----------



## stev.glasow (16. Feb 2005)

???:L  Mit dem (?! bekomme ich das irgendwie nicht hin, in der java-api-doku steht folgendes:


> *(?!X)*   	X, via zero-width negative lookahead


Was soll das bedeuten?


----------



## Wildcard (16. Feb 2005)

Du wirst die Special constructs mit dem ? verwenden müssen.
Zum Beispiel würde

```
(.*)(?=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.


----------



## stev.glasow (16. Feb 2005)

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 (16. Feb 2005)

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.

```
((.*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 (16. Feb 2005)

um den 4. Fall in den griff zu kriegen könnte man in diese Richtung gehen:

```
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.


----------



## stev.glasow (16. Feb 2005)

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


----------



## foobar (16. Feb 2005)

> 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.


----------



## stev.glasow (16. Feb 2005)

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 (17. Feb 2005)

Wildcard hat gesagt.:
			
		

> um den 4. Fall in den griff zu kriegen könnte man in diese Richtung gehen:
> 
> ```
> Pattern pat = Pattern.compile("((.*Stev)(?!.*Idiot)(.*))(ist.*)");
> ...



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.


----------



## stev.glasow (17. Feb 2005)

Jo, wäre eine Möglichkeit, arbeite nur gar nicht mit Java  :?


----------



## Wildcard (17. Feb 2005)

stevg hat gesagt.:
			
		

> Jo, wäre eine Möglichkeit, arbeite nur gar nicht mit Java


wieder so ein Verirrter!
@mods kann gelöscht werden   :lol:


----------

