views:

76

answers:

5

Consider the following Strings:

1: cccbbb

2: cccaaabbb

I would like to end up with are matches like this:

1: Array
(
    [1] => 
    [2] => bbb
)

2: Array
(
    [1] => aaa
    [2] => bbb
)

How can I match both in one RegExp?
Here's my try:

#(aaa)?(.*)$#

I have tried many variants of greedy and ungreedy modifications but it doesn't work out. As soon as I add the '?' everything is matched in [2]. Making [2] ungreedy doesn't help.

My RegExp works as expected if I omit the 'ccc', but I have to allow other characters at the beginning...

+3  A: 
/(aaa)?((.)\3*)$/

There will be an extra [3] though. I don't think that's a problem.

KennyTM
This seems to work! Would you mind explaining what the `(.)\3*` part does?
samy-delux
@samy: `(.)` matches any character (except `\n`). There are 3 capturing brackets here, and `(.)` is the 3rd one. The `\3*` part means zero or more "stuff" which is same as the 3rd match. So basically `(.)\3*` means one or more arbitrary but same characters.
KennyTM
I just figured out that this isn't it either. `bbb` can contain different characters. `bbb` was problaby not a good exmaple.
samy-delux
@samy: Please edit the question to show the actual use case.
KennyTM
A: 

here's a non-regex way. search and split on "aaa" if found, then store the rest of the right side of "aaa" into array.

$str="cccaaabbb";
if (strpos($str,"aaa")!==FALSE){
   $array[]="aaa";
   $s = explode("aaa",$str);
   $array[]=end($s);
}
print_r($array);

output

$ php test.php
Array
(
    [0] => aaa
    [1] => bbb
)

As for [1], depending on what's your criteria when "aaa" is not found, it can be as simple as getting the substring from character 4 onwards using strpos().

ghostdog74
A: 

this will match the groups but its not very flexible can you put a little more detail of what you need to do. It may be much easier to grab three characters a time and evaluate them.

Also I tested this in poweshell which has a slightly different flavor of regex.

(a{3,3})*(b{3,3})

rerun
A: 

Thanks for the brainstorming here guys! I have finally been able to figure something out that's working:

^(?:([^a]*)(aaa))?(.*)$
samy-delux
But it's not doing what you wanted. In your example 1, `\1` will contain `cccbbb`; in your example 2, `\1` contains `ccc`, `\2` contains `aaa`, and `\3` contains `bbb`.What do you *really* want to do?
Tim Pietzcker
No, in example 1 `\3´ will contain `cccbbb`, with this RegExp. `\1` can only occur in conjunction with `\2`, try it out.
samy-delux
@samy: How is this going to match `bbb` for `cccbbb`?
KennyTM
A: 

do like this:

$sPattern = "/(aaa?|)(bbb)/";

this works well.

takpar