tags:

views:

52

answers:

4

Hi can anyone tell me how to write a regex for the following scenario. The input should only be numbers or -(hyphen) or ,(comma). The input can be given as any of the following

23

23,26

1-23

1-23,24 24,25-56,58-40,45

Also when numbers is given in a range, the second number should be greater than the first one. 23-1 should not be allowed. If a number is already entered it should not be allowed again. Like 1-23,23 should not be allowed

Thanks in advance

A: 

I think with regular expressions it is better to take the time to learn them than to throw someone elses script into yours without knowing exactly what it is doing. You have excellent resources out there to help you.

Try these sites:

Those are the first three results form a google search. All are good resources. Good luck. Remember to double check what your regex is actually matching by outputing it to the screen, don't assume you know (that has bitten me more than one time).

John
A: 

I don't think you will be able to do this with a RegEx. Especially not the part about set logic - number already used, valid sequential range.

My suggestion would be to have a Regex verify the format, at the least -, number, comma. Then use the split method on commas and loop over the input to verify the set. Something like:

var number_ranges = numbers.split(',');
for (var i = 0; i < number_ranges.length; ++i) {
    // verify number ranges in set
}

That logic is not exactly trivial.

Jason McCreary
[\d]+([-|\,][\d])* does this verify the format? Or am i missing something?
Ravinandan
**Stephen P** provided a great regular expression above. Now you just need to loop thru the values and very the set.
Jason McCreary
A: 

@John

I really appreciate your suggestion and i did go thru evolt.org but couldn't figure out the part for the 1st number being greater than 2nd one in a range and also the number not getting repeated.

All i could come up with was [\d]+([-|\,][\d])* (i'm not sure if this is right)

I really appreciate if you could help me out with this

Thanks, Ravinandan

Ravinandan
Why do you insist on RegEx? If the RegEx is possible to write than it will be definitely longer than your code in Javascript and much more difficult to maintain.
MartyIX
I hope it's easier to verify the format with RegEx. So if it fails i could straight away mention the input format is wrong. If not then i could go ahead with the actual set validation and valid sequential range
Ravinandan
+3  A: 

I'm not going to quibble with "I think" or "maybe" -- you can not do this with a Regex.

Matching against a regex can validate that the form of the input is correct, and can also be used to extract pieces of the input, but it can not do value comparisons, or duplicate elimination (except in limited well defined circumstances), or range checking.

What you have as input I interpret as a comma-separated list of values or ranges of values; in BNFish notation:

value :: number
range :: value '-' value
term :: value | range
list :: term [','term]*

A regex can be built that will match this to verify correct structure, but you'll have to do other validation for the value comparisons and to prevent the duplicate numbers.

The most straigtforward regex I can think of (on short notice) is this

([0-9]+|[0-9]+-[0-9]+)(, *([0-9]+|[0-9]+-[0-9]+))*

You have digits or digits-digits, optionally followed by comma[optional space](digits or digits-digits) - repeated zero or more times.


I tested this regex at http://www.fileformat.info/tool/regex.htm with the input 3,4-12,6,2,90-221

Of course you can replace the [0-9] with [\d] for regex dialects that allow it.

Stephen P
Thanks a lot!!!! I just wrote the same reg exp with the help of your BNFish notation...Thanks again
Ravinandan