2009-10-16 13 views
5

Uso la seguente espressione regolare per convalidare un elenco di valori separati da virgole.Esiste un'espressione regolare per un elenco separato da virgole di valori discreti?

^Dog|Cat|Bird|Mouse(, (Dog|Cat|Bird|Mouse))*$ 

I valori sono anche elencati in un elenco di convalida della cella Excel basso, quindi l'utente può selezionare un singolo valore da discesa, oppure immettere più valori separati da virgole.

L'espressione regolare fa un buon lavoro di impedire all'utente di inserire qualsiasi cosa tranne i valori approvati, ma non impedisce all'utente di immettere duplicati. Ad esempio, l'utente può inserire "Cane" e "Cane, Gatto", ma l'utente può anche inserire "Cane, Cane".

C'è un modo per evitare duplicati utilizzando una singola espressione regolare simile? In altre parole, devo essere in grado di applicare un elenco discreto di valori separati da virgola approvati.

Grazie!

risposta

10

Utilizzare un backreference e un lookahead negativo:

^(Dog|Cat|Bird|Mouse)(, (?!\1)(Dog|Cat|Bird|Mouse))*$ 

EDIT: Questo non funziona con i casi come "gatto, cane, cane" ... Avrete bisogno di trovare un soluzione ibrida per tali casi - non credo che ci sia una singola regex in grado di gestirlo.


Ecco un'altra tecnica. È necessario verificare due cose, in primo luogo, che non corrisponde a questo:

(?:(?:^|,)(Dog|Cat|Bird|Mouse))+$ 

(Questo è solo una versione leggermente più corta della vostra regex originale)

Poi, controllare che non corrisponde a questo:

(Dog|Cat|Bird|Mouse).+?\1 

Es.

var valid = string.match(/(?:(?:^|,)(Dog|Cat|Bird|Mouse))+$/) && 
      !string.match(/(Dog|Cat|Bird|Mouse).+?\1/); 
+0

Sì, vicino, ma non cattura "Gatto, Cane, Cane". Grazie! – Kuyenda

+0

Non so se questo potrebbe funzionare ma forse puoi fare il riferimento posteriore (?! (\ 1 | \ 2 | \ 5 | \ 8) e cambiare il * a 4. Penso che questo potrebbe esplodere se i gruppi di cattura non esistono però. Non l'ho provato, solo un pensiero – Tim

+0

Perché "\ 1 \ 2 \ 5 \ 8"? Non sarebbe "\ 1 \ 2 \ 3 \ 4"? Grazie ! – Kuyenda

0

J-P, ho provato a modificare le espressioni regolari di esempio in modo da poter cercare i duplicati in qualsiasi stringa separata da virgole. Qualcosa del genere:

var valid = string.match(/(?:(?:^|,)([a-z]*))+$/) && 
    !string.match(/([a-z]*).+?\1/); 

Purtroppo, ho fallito. La forza è debole con me. ;)

Grazie ancora per il vostro aiuto.

Problemi correlati