# Reguläre Ausdrücke negative lookahead assertion



## takidoso (19. Juli 2010)

Hallo und Halli,
ich habe z.Z. das Bedürfnis Reguläre Ausdrücke in Java auch als Negationen verwenden zu wollen.
Sinn ist, mittels eines bestehenden FileFilters, der Reguläre Ausdrücke annimmt auch Dateien anzeigen/ausgeben zu lassen, die nicht dem Muster entsprechen.
Natürlich kann man das auch programmatisch machen, aber ich dachte es wäre doch nett, wenn man an dem FileFilter nichts mehr erweitern bräuchte.
Beim Googeln lief ich mehrmals auf den Begriff  *negative lookahead assertion*. Weiß zufällig jemand of dies auch bei Java-Regular-Expressions möglich ist?
Und wenn ja, wäre ein Beispiel sicher sehr hilfreich.

Mit erwartungsvolen und hoffenden Grüßen

Takidoso


----------



## HonniCilest (19. Juli 2010)

Ja das ist möglich. Beispiel? Hmmm ich habe bisher meistens die positive Variante benötigt...
Eventuell soetwas:

Kein besonders gutes Beispiel aber etwas besseres ist mri auf die schnelle nciht eingefallen.
Stell dir vor du überprüfst einen Mathematischen Ausdruck. Ein - kann sowohl ein Vorzeichen als auch einen Operanten darstellen. Daher willst du alle - ausgeben lassen, welche kein Vorzeichen sind.


```
Pattern p = Pattern.compile("(?<![\\+\\-\\*/])\\-");
		Matcher m = p.matcher("3+4*-5-6");
		while(m.find()) {
			System.out.println(m.group());
		}
```

Falls du dir noch die Zahl hinter dem - ausgeben lässt wirst du feststellen, dass nur -6 gefunden wird und nicht -5.


----------



## takidoso (20. Juli 2010)

Hallo HonniCilest,
Vielen Dank für Dein Beispiel.
Hast Du zufällig auch eine Seite in der das für Java genauer erklärt wird mit dem lookahead assertion?
Ich weiß halt nicht genau ob die Seite, die ich bisher fand auch so für Java gilt, andererseits die Tutorial-Seite speziell für Java-regex dieses thema nicht aufgreift.

Hier die Tutorialseite die ich sonst verwende: http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/essential/regex/
und hier de Seite die ich neulich fand unteranderem zu hiesigem Thema:http://gnosis.cx/publish/programming/regular_expressions.html
vor allem in der letzten Seite wird mit den Symbolen *?=* und *?!* umgegangen.
In Deiner Variante sehe ich *?<!*. Sind solche Kombinationen irgendwo für Java eingehend beschrieben, so dass ich, ersehen kann ob der RegEx-Java-Dialekt irgendwo abweicht, bzw es besser "studieren" kann.

Mit wissbegierigen Grüßen

Takidoso

PS: 
habe gerade mal mit meinem REGEX-Probierprogramm leider keinen Erfolge mit Deiner Beispiel-Regex gehabt, er fand nix :-/


----------



## HonniCilest (20. Juli 2010)

> vor allem in der letzten Seite wird mit den Symbolen ?= und ?! umgegangen.
> In Deiner Variante sehe ich ?<!.



Der Unterschied zwischen der Variante mit (lookbehind) bzw. ohne < (lookahead) ist die Position des Ausdrucks vor oder hinter dem anderen Ausdruck. Du hast Recht, da du speziell nach lookahead gesucht hast, hätte ich das Beispeil anders aufbauen müssen. Ein allgemeinerer Ausdruck ist Lookaround-Assertion (http://de.wikipedia.org/wiki/Regulärer_Ausdruck#Look-around_assertions
), eventuell hilft dir der Begriff auch mehr auf der Suche nach einer guten Hilfe.


----------



## takidoso (20. Juli 2010)

Ja das ist eine nette Hilfeseite...
Jedoch steht da was von Perl 5.
Demnach gibt es in Java offenbar dieses Lookahead/-behind nicht, das wäre dann auch eine Erklärung, warum Dein Ausdruck nicht funktioniert.
Oder ist das ne Frage der Java-Version?
Mit welcher Version hast Du Deinen Ausdruck erfolgreich ausprobieren können?


----------



## HonniCilest (20. Juli 2010)

jdk1.6.0_13
jre6

Ich hab' einfach mal beides aufgeschrieben, weil ich mir nie merken kann, was wofür benötigt wird... Ich nutze aber mittlerweile sehr oft Lookaround-Assertions, ich weiß, dass es geht!

Edit:
Ich hab mir mal ein Beispiel ausgedacht mit negativ Lookahead...
Stell dir vor du hast ein Liste von Namen und willst alle Vornamen von den Leuten herausfinden, deren Nachnamen nicht dem Namen XXXX entsprechen.

```
Pattern p = Pattern.compile("\\p{Alpha}+ (?!Mustermann)");
		Matcher m = p.matcher("Maria Musterfrau, Max Mustermann, Marta Musterfrau, Martin Mustermann");
		while(m.find()) {
			System.out.println(m.group());
		}
```

Ausgabe:

```
Maria 
Marta
```


----------

