tags:

views:

99

answers:

5

Is it possible to write a regular expression to check whether all numbers of specific 10 digit number occured up to 3 times? for example return value for Regex.IsMatch("xxxx", "4433425425") is false. and for Regex.IsMatch("xxxx", "4463322545") is true. what is xxxx? in the first one i have 4 occurrence of digit 4 and in second one non of digits occurred more than 3 times.

+3  A: 

Find a number occurring three times in a row:

(?=(0{3}|1{3}|2{3}|3{3}|4{3}|5{3}|6{3}|7{3}|8{3}|9{3}).{3}

Find a number occurring three times anywhere in the string:

(.?0.?){3}|(.?1.?){3}|(.?2.?){3}|(.?3.?){3}|(.?4.?){3}|(.?5.?){3}|(.?6.?){3}|(.?7.?){3}|(.?8.?){3}|(.?9.?){3}

Using backreferences (C/O @rerun):

([0-9]).*\1.*\1.*

NOTE: this will check the entire string for multiple characters. There is no limitation to the first 10 characters in the string. Let me know if you need that.

Brad
I've edited the question. no its not my answer
SaeedAlg
@Saeed, see my updated answer
Brad
@Brad, thanks, I can't understand it but i test it with "2262345354" and i got false answer it should be true.
SaeedAlg
I always see the [0-9] groping notation instead of the \d is there a reason aren't they the same.
rerun
@rerun, `\d` can match any unicode digit, not only 0-9. See comment by Lucero on http://stackoverflow.com/questions/3959810/percentage-regex
Brad
good to know. I've used \d since I was coding perl 10 years ago
rerun
@Saeed, I shouldn't have been using the zero-width look-ahead. I've corrected it, but I still say that @rerun's use of backreferences is superior if your engine understands it.
Brad
+1 Regular Expressions are still a mystery to me! =P
Will Marcouiller
A: 

None of the examples have all digits repeat 3 times or should the regex contain a digit to test for?

David Mårtensson
He's not looking for them to all repeat three times - he just wants to make sure that no single digit is repeated more than 3 times in the sequence.
Irfy
A: 

Yes it is possible as number of possible combinations is finished, but I do not see any simple way.

kriss
Is this really an answer?
Brad
Well, he didn't asked how ? Isn't it ? And as you can see the accepted answer just check that at least one digit is repeated three times (not all digits repeated 3 times) and to me it looks even *less* like an answer. Mine at least is correct.
kriss
The accepted answer works fine, its not consider 10 digit, and check whether a bad number exists or not is enough to find just one bad number.
SaeedAlg
@Kriss, now i know what do you say about the combintion, ... , in the way you think is enough to check 10 + 10!/(2!*8!) + 10!/(7! * 3!) not all combination because the length of string is 10 so just numbers with 1 or 2 or 3 can be repeated, if you can find a regular expression for it, it will be very interesting to me.
SaeedAlg
@saeedalg: read my comment below question. The problem I had was the way the question was asked it was hard to say what was wanted. One interpretation was easy to check (at most 3 identical digits), but I was looking for the other one: how to check that all digits of the number occurs less than 3 times.
kriss
+7  A: 

Will match any digit that has four or more instances

 string found =  Regex.Match(s,@"(\d).*\1.*\1.*\1").Groups[1].Value;

Just an example of how to use it

static void Main( string[] args )
{
     string fail = "1234567890";
     string s = "1231231222";
     string mTxt = @"(\d).*\1.*\1.*\1";
     Console.WriteLine( Regex.Match(s,mTxt).Success);
     Console.WriteLine(Regex.Match(fail, mTxt).Success);
}

Baised on @Brads Comments below use

([0-9]).*\1.*\1.*\1
rerun
+1 for using backreferences. I incorporated your answer into mine (and attributed you credit)
Brad
@Brad - kinda funny. "Nice answer. Maybe I can get some rep for it too."
Corbin March
It's just checking that at least **one** digit is repeated four times. Was it really the question ?
kriss
He wanted to see that no character had at most three occurences the same as if any character has four
rerun
+1  A: 

I'm going to risk downvotes here and suggest that regexes are most likely not the best tool for this job.

They have their place but I usually find that, if you're getting into "horrendous" territory with multiple backtracking or negative lookahead and lots of or clauses, you're probably better off tossing away the whole regex idea and writing a simple string scanning function which simply count each digit and ensures the counts are correct at the end. Pseudo-code something like:

def isValid (str):
    foreach ch in '0'..'9':
        count[ch] = 0
    foreach ch in str:
        if ch not in '0'..'9':
            return false
        count[ch] = count[ch] + 1
    foreach ch in '0'..'9':
        if count[ch] > 3:
            return false
    return true

That's my advice, take it or leave it, I won't be offended :-)

paxdiablo
I'd got your advice, but its a good challenge:D.
SaeedAlg
@SaeedAlg, it _is_ a good challenge. Unfortunately it's 11pm Fri night and I need to watch Big Bang Theory then get some sleep for the kids' sports stuff tomorrow. So I'll have to stick with the answer I gave :-) I'll keep an eye on this though since I'm interested (mostly in the readability of solutions).
paxdiablo