# RegEx - Worte ausschließen



## Pfaeff (19. Dez 2009)

Hallo,

Ich habe einen regulären Ausdruck der Worte einer bestimmten Form akzeptiert.
Nehmen wir mal als Beispiel "[a-z]*". Nun möchte ich aber, dass einige Worte nicht erlaubt sind, beispielsweise "cde".
Bisher mache ich es so, dass ich abfrage 
	
	
	
	





```
if (wort == "cde") return false;
```
. 
Ich möchte dies allerdings in den regulären Ausdruck integrieren. Ich habe schon einiges versucht, z.B.
"^(\bcde\b)&&[a-z]*" aber dies scheint nicht zu funktionieren.
Gibt es eine Möglichkeit, so etwas zu realisieren? 

Vielen Dank


----------



## Sekundentakt (19. Dez 2009)

> '/maria(?!\x20+müller|müller)/i'


Dieser reguläre Ausdruck würde alle Marias finden, die nicht "Maria Müller" bzw. "MariaMüller" heißen.


----------



## Pfaeff (19. Dez 2009)

Kannst du mir den Ausdruck erklären, ich verstehe noch nicht so ganz, wie das funktioniert.


----------



## Sekundentakt (20. Dez 2009)

Schau mal hier nach: Reguläre Ausdrücke

Das \x20 steht für ein Leerzeichen.

Mit dem Fragezeichen definiere ich, dass Müller ein bzw. keinmal vorkommt. Durch das anschließende Ausrufezeichen definiere ich dann, dass Müller zwar ein bzw. keinmal vorkommt, aber wenn es vorkommt, soll es negiert (nicht gematcht) werden.
Das "|" ist eine Oder-Bedingung. Also entweder steht hinter Maria "LEERZEICHEN Müller" oder nur "Müller". Wenn das der Fall ist, dann wird sie nicht gefunden.
Heißt sie aber Maria Mustermann wird sie gefunden.


----------



## Pfaeff (20. Dez 2009)

Das habe ich soweit verstanden. Vielleicht ist das Beispiel auch ein wenig ungünstig gewählt.
Mit (?!cde) könnte ich sagen, dass nach dem vorhergehenden Wort, cde nicht kommen darf, wie kann ich jetzt aber weitere Bedingungen spezifizieren? Nehmen wir mal mein Beispiel:

Worte aus [a-z]* und cde und xyz sind nicht erlaubt. Wäre das so etwas? ([a-z]*)&&(?!cde)&&(?!xyz) ?


----------



## André Uhres (20. Dez 2009)

Versuch's mal so:

```
import java.util.regex.*;
public class Regex {
    public Regex() {
        test("aha cde oho 123 cdee xyz");//aha oho cdee
    }
    private void test(final String subjectString) {
// \b(?:(?!(?>\bcde\b|\bxyz\b))[a-z])+\b
//
// Assert position at a word boundary «\b»
// Match the regular expression below «(?:(?!(?>\bcde\b|\bxyz\b))[a-z])+»
//    Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
//    Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?!(?>\bcde\b|\bxyz\b))»
//       Atomic group.  Match the regex below, and do not try further permutations of it if the overall match fails. «(?>\bcde\b|\bxyz\b)»
//          Match either the regular expression below (attempting the next alternative only if this one fails) «\bcde\b»
//             Assert position at a word boundary «\b»
//             Match the characters "cde" literally «cde»
//             Assert position at a word boundary «\b»
//          Or match regular expression number 2 below (the entire group fails if this one fails to match) «\bxyz\b»
//             Assert position at a word boundary «\b»
//             Match the characters "xyz" literally «xyz»
//             Assert position at a word boundary «\b»
//    Match a single character in the range between "a" and "z" «[a-z]»
// Assert position at a word boundary «\b»
        Pattern regex = Pattern.compile("\\b(?:(?!(?>\\bcde\\b|\\bxyz\\b))[a-z])+\\b");
        Matcher regexMatcher = regex.matcher(subjectString);
        while (regexMatcher.find()) {
            System.out.print(regexMatcher.group() + " ");
        }
        System.out.println("");
    }
    public static void main(String[] args) {
        new Regex();
    }
}
```


----------



## Sekundentakt (20. Dez 2009)

Ich verstehe den Sinn gerade nicht.
Wenn Du Worte mit allen Buchstaben von a-z ausschließen willst, brauchst Du auf den Rest nicht mehr prüfen. Meinst Du aber, dass Du alle Worte a-z matchen willst, außer cde und xyz (wie im Eingangsposting erwähnt), dann ist der Code fast richtig.



> (?!cde)&&(?!xyz)


Mit diesem Teil schließt Du nur die Zeichenfolgen cde und xyz aus. Sprich, wenn dein Wort Javaxyz heißt, wird es nicht gematcht.
Heißt es aber Xylophon wird es gematcht. 
Nach deinem obigen RegEx-Fragment würdest Du alle Worte ausschließen, die die Zeichen cde UND xyz enthalten. Ich glaube aber, dass Du eher meinst: schließe alle Worte aus, die cde ODER xyz enthalten, richtig?

Wenn cde und xyz aber für ganze Worte stehen sollen, würde ich vor und nach cde/xyz noch Leerzeichen setzen. Deinen String, den du prüfen willst, müsstest du aber auch verändern: Du musst an den Anfang und an das Ende Leerzeichen ranhängen.


----------



## André Uhres (20. Dez 2009)

Ich hab's so verstanden:
Alle Worte aus [a-z]+ mit Ausmahme der Worte "cde" und "xyz".
Mein obiger Code zeigt eine mögliche Implementierung.


----------



## Pfaeff (20. Dez 2009)

Genau so hab ich's gemeint und es funktioniert super, vielen Dank


----------

