6

How can I get a regular expression that matches any string that has two or more commas?
I guess this is better explained with an example of what should match and what shouldn't

abcd,ef // Nop
abc,de,fg // Yup

// This is what I have so far, but it only matches consecutive commas
var patt = /\,{2,}/;

I'm not so good with regex and i couldn't find anything useful. Any help is appreciated.

elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • Are you saying you don't want consecutive colons to match? (Or just that that is all you've managed to match so far?) Your examples don't cover it either way. And are you looking for colons (:) or commas (,)? – nnnnnn Feb 13 '12 at 05:10
  • Oh commas, typo. I'm looking to match any string that has two or more commas no matter where they are. – elclanrs Feb 13 '12 at 05:13

2 Answers2

15

This will match a string with at least 2 commas (not colons):

/,[^,]*,/

That simply says "match a comma, followed by any number of non-comma characters, followed by another comma." You could also do this:

/,.*?,/

.*? is like .*, but it matches as few characters as possible rather than as many as possible. That's called a "reluctant" qualifier. (I hope regexps in your language of choice support them!)

Someone suggested /,.*,/. That's a very poor idea, because it will always run over the entire string, rather than stopping at the first 2 commas found. if the string is huge, that could be very slow.

Alex D
  • 29,755
  • 7
  • 80
  • 126
  • OMG thanks! Seriously I couldn't figure this one out. Can you explain a little bit why this works? I looked everywhere for answers and still can't wrap my head around it. I'll accept your answer in 5 min just can't now. – elclanrs Feb 13 '12 at 05:14
  • Oh, I think I know why...Funny thing is I asked this question to be able to solve another one. – elclanrs Feb 13 '12 at 05:19
  • 1
    He simply said "two or more commas", he didn't say they had to be separated by a non-comma. Thus, `,.*,` might be a more appropriate fit. – mpen Feb 13 '12 at 05:20
  • @elclanrs, I just added some explanation to the answer. If you are trying to solve another problem, post another question, and link to it here. – Alex D Feb 13 '12 at 05:33
  • 2
    @Mark, sorry, but the regexp I posted is better. It will match any string with 2 commas, and is far more efficient than yours, especially if the string is very long. – Alex D Feb 13 '12 at 05:35
  • [This is the question](http://stackoverflow.com/questions/9255142/how-to-check-user-inputted-decimal-separator-in-the-textbox-by-jquery/9256032#9256032) I was trying to solve. I've a similar problem in one of my forms and this worked like a charm. I used **Mark's** answer tho. Why is yours is more efficient for long strings? – elclanrs Feb 13 '12 at 05:38
  • See the edited answer for the reason why Mark's regexp is inefficient. – Alex D Feb 13 '12 at 05:40
  • I see you edited your answer to explain this. Seems like for my purpose it wouldn't make a big difference in performance, since my input has a `max-length` of 30. – elclanrs Feb 13 '12 at 05:41
  • In that case, just use whichever you prefer. Either will work. – Alex D Feb 13 '12 at 05:49
  • @AlexD: I've only heard of `.*?` referred to as "lazy" (as opposed to "greedy"). I'm skeptical about `,.*?,` being more or less efficient than the greedy version; I would imagine it would depend on the implementation and the method used. For example, a "test" or "IsMatch" function (that returns a bool, not a match object) ought to bail at the first match. Of course, performance testing would be required, but to say "far more efficient" is a bit of a bold statement. We're talking less than a millisecond in most use cases. – mpen Feb 13 '12 at 06:11
  • In fact, I went ahead and tested it: http://jsperf.com/greedy-vs-non-greedy-regex The greedy version actually performed 19% better in FF10. – mpen Feb 13 '12 at 06:16
  • @Mark, thanks for this information (I will update my answer later). I imagine your test string had a comma close to the beginning, and a comma close to the end. Unless FF10 has a very inefficient implementation of lazy/reluctant qualifiers, that's the only way I can think of that .* would be faster. On a (40,000 character) test case I just tried (on Ruby 1.9), .*? was faster by a factor of 2000x. – Alex D Feb 13 '12 at 06:52
  • @Mark, that `jsperf.com` site is awesome, I've never seen it before! Looking at your test case confirmed my suspicion. Here is another for comparison: http://jsperf.com/greedy-vs-non-greedy-regex/2 – Alex D Feb 13 '12 at 07:00
1

if you want to get count of commas in a given string, just use /,/g , and get the match length

'a,b,c'.match(/,/g);    //[',',','] length equals 2<br/>
'a,b'.match(/,/g);    //[','] length equals 1<br/>
'ab'.match(/,/g)    //result is null
mpen
  • 272,448
  • 266
  • 850
  • 1,236
chameleon
  • 11
  • 2