views:

176

answers:

3

I need advice on this snippet

$text = preg_replace('|(A.*)?A(.*)C|', '$1foo$2bar', $text);

This will match ABC in "AB ABC D", and replace it with "AB fooBbar D"; as you can see this matches the "AB " part at the beginning as well, which I have to repeat in the replacement string with $1, in order not to lose it.

Is this the best way to get such a result?

Is there a flag X such that

$text = preg_replace('|A(.*)C|X', 'foo$1bar', $text);

produces the same result?

I hope I've been clear

Thank you!

EDIT: Consider A,B,C as atomic strings of arbitrary characters, they can contain whitespaces as well

Also, the presented example is in fact buggy, as it matches only the second "ABC" in "ABC ABC".

EDIT2: I'm sorry, I've probably explained the problem very badly. The point is I'd want to match whatever is between two A,C string, so that there is no substring A in the match

Again thanks

+1  A: 

How about this:

$text = preg_replace('|A(\S*)C|', 'foo$1bar', $text);

The \S matches a non-whitespace character, so you won't replace across different words.


After seeing some of the OP's comments, I'll hazard another guess:

$text = preg_replace('|A(B)C|', 'foo$1bar', $text);
Zach Scrivena
Nice, but I needed to match white space as well, I meant ABC as arbitrary A,B,C strings, I should probably explain that better.
NoWhereMan
+1  A: 

Use the non-greedy version of the * quantifier :

$text = preg_replace('|(.*)(A.*?C)|', '$1foo$2bar', $text);
kmkaplan
I've tried that and it matches AABC in "AABC", and not only ABC
NoWhereMan
Right, edited to add a greedy match at the beginning.
kmkaplan
A: 

As the question has been clarified, try this expression:

preg_replace('/(?:A)+(.+?)(?:C)+/', 'foo$1bar', $text)

An example:

$A = 'abc'; $B = '123'; $C = 'xyz';
$text = "$A$B$C $A$A$B$C $A$B$C$C";
echo preg_replace("/(?:$A)+(.+?)(?:$C)+/", 'foo$1bar', $text);
Gumbo
A(.+?)Cmatches A C B C as well, and [^C] it's not suitable since C is in fact a string (e.g. it might be 'foo'); sorry, I've probably edited the description while you were giving your answer
NoWhereMan
I think this is the best one, thank you
NoWhereMan