2010-02-03 10 views
5

Ich habe jetzt meinen Kopf gegen diese seit einiger Zeit hämmern: Ich möchte alle [a-z]+[0-9]? Zeichenfolgen ohne Saiten erfassen, wie sin|cos|tan usw. Also meine regex Hausaufgaben gemacht haben, die folgende regex sollte funktionieren:java regex ausschließen bestimmte Zeichenfolgen aus einer größeren

(?:(?!(sin|cos|tan)))\b[a-z]+[0-9]? 

Wie Sie sehen, ich bin mit negativem Look-Ahead zusammen mit Wechsel - die \b, nachdem die nicht-Erfassung Gruppe schließender Klammer kritisch ist die in von sin zu vermeiden passenden usw. die Regex macht Sinn und In der Tat habe ich es mit RegexBuddy und Java als Zielimplementierung und erhält das gewünschte Ergebnis, aber es funktioniert nicht mit Java Matcher und Pattern-Objekten! Irgendwelche Gedanken?

prost

+0

Hinweis: Ich glaube nicht, dass Sie brauchen??: 'Wenn Sie'?! '' Verwenden. –

+0

das?: Ist für das nicht erfassen der Gruppen mit Rückreferenzen, es ist da für Leistung und sollte kein Problem sein. Aber ich habe es ohne Erfolg versucht – nvrs

+1

Wenn Sie einige Beispieleingaben gepostet haben und was Sie von der Ausgabe in jedem Fall erwarten, denke ich, dass mehr Leute in der Lage wären zu helfen. – ninesided

Antwort

6

Die \b ist an der falschen Stelle. Es würde nach einer Wortgrenze suchen, die sin/cos/tan vor es nicht hatte. Aber eine Grenze nur nach irgendwelche von denen würde einen Buchstaben am Ende haben, so dass es ein Ende der Wortgrenze sein müsste, die nicht sein kann, wenn das nächste Zeichen a-z ist.

Auch würde das negative Lookahead (wenn es funktionierte) Strings wie cost ausschließen, was ich nicht sicher bin, dass Sie wollen, wenn Sie nur Schlüsselwörter herausfiltern.

Ich schlage vor:

\b(?!sin\b|cos\b|tan\b)[a-z]+[0-9]?\b 

Oder, einfacher gesagt, man muss nur \b[a-z]+[0-9]?\b passen könnte und danach die Strings in der Keyword-Liste herauszufiltern. Sie müssen nicht immer alles in Regex tun.

+0

Übereinstimmungen 'cos1' aber es sollte nicht (wenn ich die Anforderung richtig verstanden habe). – Tomalak

+1

@Tomalak: Nein, das negative Lookahead soll mit ganzen Wörtern, nicht mit Präfixen übereinstimmen. Wenn es eine trigonale Funktion namens 'cos1' gäbe, würde sie folgendermaßen aufgelistet werden:' (?! (?: sin | cos1? | Tan) \ b) ' –

+0

Ja, die Anforderungen sind nicht ganz klar, aber das war es meine Vermutung. – bobince

1

So mögen Sie [a-z]+[0-9]? (eine Folge von mindestens einem Buchstaben, gegebenenfalls gefolgt von einer Ziffer), es sei denn, dass Buchstabenfolge costan einer der sin ähnelt?

\b(?!(sin|cos|tan)(?=\d|\b))[a-z]+\d?\b 

Ergebnisse:

 
cos - no match 
cosy - full match 
cos1 - no match 
cosy1 - full match 
bla9 - full match 
bla99 - no match 
+0

Hallo, danke für die Antwort, aber ich bekomme immer noch keine Übereinstimmungen. Ich sehe, dass basierend auf dem, was ich sagte, Sie Streichhölzer wie gemütlich etc. hinzugefügt, die richtig ist, aber mit: Pattern p = Pattern.compile ("\ b (?! (Sin | cos | tan))?" = [^ Az] | \ b)) [az] + [0-9]? \ b "); Matcher m = f.matcher (stringToMatch); Ich bekomme überhaupt keine Treffer! – nvrs

+0

In Java-Zeichenfolgen müssen Backslashes maskiert werden. Ich habe den reinen Regex gezeigt. Natürlich müssen Sie es selbst an die String-Escaping-Regeln Ihrer Programmiersprache anpassen. – Tomalak

0

i vergessen, die \b für Java zu entkommen so \b\\b sein sollte und es funktioniert jetzt. cheers

+0

Wenn Sie Regex-Fragen veröffentlichen, ist es eine gute Idee, die Regex genau so einzufügen, wie sie in Ihrem Quellcode erscheint. '\ bfoo \ b' sieht gut aus, aber' "\ bfoo \ b" 'wirft wahrscheinlich Fragen auf, sogar von Leuten, die Java nicht sprechen und nicht sicher sind, wie seine String-Literale funktionieren. –

+0

Haben Sie auch versucht, RegexBuddy den Java-Quellcode zu generieren? (Das ist die Registerkarte "Verwenden", falls Sie es nicht wissen.) Ich habe den automatisch generierten Quellcode nie gemocht, aber manchmal benutze ich "Verwenden", um mich an die Regeln für Sprachen zu erinnern, die ich nicht fließend beherrsche . –