2010-02-03 12 views
5

ho sbattere la testa contro questo da qualche tempo: voglio catturare tutte le sequenze di caratteri [a-z]+[0-9]? escluso stringhe come sin|cos|tan ecc Quindi, dopo aver fatto il mio dovere l'regex seguenti regex dovrebbe funzionare:java regex escludere stringhe specifiche da uno più grande

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

Come vedi io sto usando lookahead negativo con alternanza - il \b dopo la non-cattura parentesi di chiusura di gruppo è fondamentale per evitare che corrisponde al in di sin ecc l'espressione regolare ha un senso e in effetti ho provato con RegexBuddy e Java come implementazione di destinazione e ottenere il risultato desiderato ma non funziona con gli oggetti Java Matcher e Pattern! Qualche idea?

applausi

+0

Nota: non penso che tu abbia bisogno di '?:' Quando usi '?!'. –

+0

il?: Serve per non catturare i gruppi con le sottorappresentazioni, è lì per le perfomance e non dovrebbe essere un problema. Ma ho provato senza inutilmente lo – nvrs

+1

se hai postato alcuni esempi di input e cosa ti aspetti dall'output in ogni caso, penso che più persone sarebbero in grado di aiutare. – ninesided

risposta

6

Il \b è nel posto sbagliato. Sarebbe alla ricerca di un limite di parole che non aveva sin/cos/tan prima di it. Ma un limite solo dopo uno di quelli avrebbe una lettera alla fine, quindi dovrebbe essere un confine di fine parola, che non può essere se il carattere successivo è a-z.

Inoltre, il lookahead negativo avrebbe (se funzionasse) escludere stringhe come cost, che non sono sicuro di volere se si limitano a filtrare le parole chiave.

suggerisco:

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

O, più semplicemente, si può solo corrispondere \b[a-z]+[0-9]?\b e filtrare le stringhe nella elenco di parole chiave in seguito. Non devi sempre fare tutto in regex.

+0

Corrisponde a 'cos1' ma non dovrebbe (se ho capito correttamente il requisito). – Tomalak

+1

@Tomalak: No, il lookahead negativo è inteso per corrispondere a parole complete, non a prefissi. Se ci fosse una funzione trigonometrica chiamata 'cos1', sarebbe elencata come tale:' (?! (?: sin | cos1? | Tan) \ b) ' –

+0

Sì, i requisiti non sono del tutto chiari, ma quello era la mia ipotesi – bobince

1

Così si vuole [a-z]+[0-9]? (una sequenza di almeno una lettera, eventualmente seguito da una cifra), a meno che quella sequenza lettera analogo a uno dei sincostan?

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

risultati:

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

Ciao, grazie per aver risposto, ma non riesco ancora a ottenere alcuna corrispondenza. Vedo che in base a ciò che ho detto hai aggiunto corrispondenze come cozy ecc. Che è corretto ma usando: Pattern p = Pattern.compile ("\ b (?! (Sin | cos | tan) (? = [^ Az] | \ b)) [az] + [0-9] \ b ");? Matcher m = f.matcher (stringToMatch); non ho nessuna corrispondenza! – nvrs

+0

Nelle stringhe di stringhe Java è necessario eseguire il escape. Ho mostrato la regex pura. Ovviamente è necessario adattarlo alle regole di escape delle stringhe del proprio linguaggio di programmazione. – Tomalak

0

ho dimenticato di sfuggire alla \b per Java in modo \b dovrebbe essere \\b e funziona ora. evviva

+0

Quando si postano domande regex, è una buona idea includere la regex esattamente come appare nel codice sorgente; '\ bfoo \ b' va bene, ma' '\ bfoo \ b" 'è probabile che sollevi domande, anche da persone che non parlano Java e non sono sicuro di come funzionino le sue stringhe letterali. –

+0

Inoltre, hai provato ad avere RegexBuddy a generare il codice sorgente Java? (Questa è la scheda "Usa", nel caso non lo sapessi.) Non mi è mai piaciuto il codice sorgente generato automaticamente, ma a volte uso "Usa" per ricordare a me stesso le regole di escape per le lingue in cui non parlo fluentemente . –

Problemi correlati