How can I build a regular expression that will match a string of any length containing any characters but which must contain 21 commas?
if exactly 21:
/^[^,]*(,[^,]*){21}$/
if at least 21:
/(,[^,]*){21}/
However, I would suggest don't use regex for such simple task. Because it's slow.
Might be faster and more understandable to iterate through the string, count the number of commas found and then compare it to 21.
^(?:[^,]*)(?:,[^,]*){21}$
/^([^,]*,){21}[^,]*$/
That is:
^ Start of string
( Start of group
[^,]* Any character except comma, zero or more times
, A comma
){21} End and repeat the group 21 times
[^,]* Any character except comma, zero or more times again
$ End of string
var valid = ((" " + input + " ").split(",").length == 22);
or...
var valid = 21 == (function(input){
var ret = 0;
for (var i=0; i<input.length; i++)
if (input.substr(i,1) == ",")
ret++;
return ret
})();
Will perform better than...
var valid = (/^([^,]*,){21}[^,]*$/).test(input);
If you're using a regex variety that supports the Possessive quantifier (e.g. Java), you can do:
^(?:[^,]*+,){21}[^,]*+$
The Possessive quantifier can be better performance than a Greedy quantifier.
Explanation:
(?x) # enables comments, so this whole block can be used in a regex.
^ # start of string
(?: # start non-capturing group
[^,]*+ # as many non-commas as possible, but none required
, # a comma
) # end non-capturing group
{21} # 21 of previous entity (i.e. the group)
[^,]*+ # as many non-commas as possible, but none required
$ # end of string