Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a regular expression for a comma separated list of discrete values?

Tags:

regex

excel

I use the following regular expression to validate a comma separated list of values.

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

The values are also listed in a drop down list in Excel cell validation, so the user can select a single value from the drop down list, or type in multiple values separated by commas.

The regular expression does a good job of preventing the user from entering anything but the approved values, but it doesn't prevent the user from entering duplicates. For example, the user can enter "Dog" and "Dog, Cat", but the user can also enter "Dog, Dog".

Is there any way to prevent duplicates using a similar single regular expression? In other words I need to be able to enforce a discrete list of approved comma separated values.

Thanks!

like image 955
Kuyenda Avatar asked Oct 16 '09 15:10

Kuyenda


People also ask

How do you include a comma in regular expressions?

The 0-9 indicates characters 0 through 9, the comma , indicates comma, and the semicolon indicates a ; . The closing ] indicates the end of the character set. The plus + indicates that one or more of the "previous item" must be present.

Can a regular expression be empty?

∅, the empty set, is a regular expression. ∅ represent the language with no elements {}.


2 Answers

Use a backreference and a negative lookahead:

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

EDIT: This won't work with cases such as "Cat, Dog, Dog" ... You'll need to come up a hybrid solution for such instances - I don't believe there is a single regex that can handle that.


Here's another technique. You need to check two things, first, that it DOES match this:

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

(That's just a slightly shorter version of your original regex)

Then, check that it DOES NOT match this:

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

E.g.

var valid = string.match( /(?:(?:^|, )(Dog|Cat|Bird|Mouse))+$/ ) &&
           !string.match( /(Dog|Cat|Bird|Mouse).+?\1/ );
like image 146
James Avatar answered Oct 16 '22 12:10

James


J-P, I tried editing your sample regular expressions so that I could look for duplicates in any comma separated string. Something like this:

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

Unfortunately, I failed. The Force is weak with me. ;)

Thanks again for your help.

like image 23
Kuyenda Avatar answered Oct 16 '22 12:10

Kuyenda