tags:

views:

81

answers:

5

I've searched the questions but can't find an answer. I need a pattern that, used with php preg_match function, only match strings that does not contains 3 or more consecutive digits, e.g.:

rrfefzef        => TRUE
rrfef12ze1      => TRUE
rrfef1zef1      => TRUE
rrf12efzef231   => FALSE
rrf2341efzef231 => FALSE

So far, I have wrote the following regex:

@^\D*(\d{0,2})?\D*$@

it only match the strings that have only one occurrence of \d{0,2}

If someone else has time to help me with this, I would appreciate it :)

Regards,

A: 
/^(.(?!\d\d\d))+$/

Matches all characters that are not followed by three digits. Example.

poke
Thanks a lot, it works fine! :)
garmr
A: 

You could search for \d\d, which will match on all the bad strings. Then you can adjust your further program logic to correctly react to that.

If you really need a "positive" match on strings that contain adjacent digits, this should also work:

^\D?(\d?\D)*$
sth
A: 

Is there anything stopping you from simply prefixing the preg_match() function with "!", thereby reversing the boolean result?

!preg_match( '/\d{2,}/' , $subject );

Is so much easier...

Lucanos
Depends on whether we are considering his test cases, or his written spec - it satisfies "_...does not contains 2 or more consecutive digits_", but the test cases seem to be 3 or more. And then, looking at the test cases again, he may mean 3 or more _sequential_ digits (ie "**123**" = True, but "**134**" = False).
Lucanos
In fact I'm using a framework that, in this case, encapsulate preg_match return so I can't just reverse preg_match result. I could have used a callback instead but I prefer the regex approach ;)
garmr
A: 

If I interprete your requirement correct, following regex matches your valid inputs without matching the invalid inputs.

^\D*\d*\D*\d?(?!\d+)$

is explained as follows

> # ^\D*\d*\D*\d?(?!\d+)$
> # 
> # Options: case insensitive; ^ and $ match at line breaks
> # 
> # Assert position at the beginning of a line (at beginning of the string or
> after a line break character) «^»
> # Match a single character that is not a digit 0..9 «\D*»
> #    Between zero and unlimited times, as many times as possible, giving back
> as needed (greedy) «*»
> # Match a single digit 0..9 «\d*»
> #    Between zero and unlimited times, as many times as possible, giving back
> as needed (greedy) «*»
> # Match a single character that is not a digit 0..9 «\D*»
> #    Between zero and unlimited times, as many times as possible, giving back
> as needed (greedy) «*»
> # Match a single digit 0..9 «\d?»
> #    Between zero and one times, as many times as possible, giving back as
> needed (greedy) «?»
> # Assert that it is impossible to match the regex below starting at this
> position (negative lookahead)
> «(?!\d+)»
> #    Match a single digit 0..9 «\d+»
> #       Between one and unlimited times, as many times as possible,
> giving back as needed (greedy) «+»
> # Assert position at the end of a line (at the end of the string or before a
> line break character) «$»
Lieven
+1  A: 

Reject the string if it has two or more consecutive digits: \d{2,}

Or use negative lookahead to match only if there are no consecutive digits: ^(?!.*\d{2}).*$

Amarghosh