2009-07-23 9 views
13

ho cercato attraverso così e anche se la questione è stata risolta in uno scenario:Regex per abbinare un modello, ma esclude un insieme di parole

Regex to match all words except a given list

Non è proprio quello che sto cercando . Sto cercando di scrivere un'espressione regolare che corrisponda a qualsiasi stringa della forma [\ w] + [(], ma che non corrisponde alle tre stringhe "cat (", "dog (" e "sheep" specificatamente

ho giocato con lookahead e lookbehind, ma non riesco a raggiungerlo. I può essere overcomplicating questo, in modo che qualsiasi aiuto sarebbe molto apprezzato.

risposta

21

Se l'implementazione delle espressioni regolari supporta look-ahead or look-behind assertions, è possibile utilizzare la seguente:

  • Utilizzando un look-ahead negativo affermazione:

    \b(?!(?:cat|dog|sheep)\()\w+\(
    
  • Utilizzando un negativo look-dietro affermazione:

    \b\w+\((?<!\b(?:cat|dog|sheep)\() 
    

ho aggiunto l'ancora \b che segna una word boundary. Quindi catdog( corrisponderebbe anche se contiene dog(.

Ma mentre affermazioni look-ahead sono più ampiamente supportati da implementazioni regex, la regex con l'affermazione look-dietro è più efficiente dal momento che è testato solo se l'espressione regolare precedente (nel nostro caso \b\w+\() ha già fatto partita. Tuttavia, l'asserzione look-ahead sarebbe stata testata prima dello in modo che la regex effettiva corrispondesse. Quindi nel nostro caso l'asserzione look-ahead viene testata ogni volta che \b corrisponde.

+1

Il secondo è molto probabilmente efficiente poiché non controlla ogni singola posizione con un look-out negativo (vale la pena notare che sono negativi). Inoltre, penso che potrebbe essere meglio mettere il negativo guardare indietro dopo la parentesi e includere una parentesi nel look-behind. In questo modo, eseguirà un lookback aggiuntivo solo quando troverà una possibile corrispondenza, anziché per ogni parola nella stringa. – Blixt

+0

@Blixt: buon punto. – Gumbo

+0

Inoltre, la prima espressione regolare rifiuterà 'catastrofe (', 'dogmatic (' e 'sheepily ('. Il tuo secondo è stato salvato da un errore simile da '\ b' nel look-behind. – rampion

3

Ne hai davvero bisogno in una singola espressione regolare? In caso contrario, l'implementazione più semplice è costituita da due regex: una per controllare che non corrisponda a una delle parole proibite e una per abbinare il tuo \ w +, concatenato con un AND logico.

Problemi correlati