The looking for excess of each is best handled like the existing $regex() in my opinion. To count them with a while loop would be wasteful.

Now that I think about it a bit further, you should probably include the initial $len($3-) that Lpfix5 had there, so as not to bother doing a check if the string is less than 49 characters (as you're min. count is 49, it will never match a string that's 20 characters long. to just skip the checks when they aren't needed basically).