Question

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

Was it helpful?

Solution

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);

OTHER TIPS

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);

Use the non-greedy version of the * quantifier :

$text = preg_replace('|(.*)(A.*?C)|', '$1foo$2bar', $text);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top