0

I know there is a negative lookahead regex that can match last occurrences of the string.

Example: replace last occurrences of string

I want to do something like this.

Example:

$string = 'hello example (a) hello example (b) (c)';
echo preg_replace('/\(.*?\)(?!.*\(.*?\))/', '', $string);

What I trying to do is to replace the last occurrences of (.*) but I failed. The output I got is hello example. It replaces the entire first ( and the last ) which is (a) hello example (b) (c).

My expected out put is hello example (a) hello example (b).

Any one can give some cue? What is the correct regex to achieve what I want. Thank you very much.

Community
  • 1
  • 1
overshadow
  • 958
  • 2
  • 15
  • 31

2 Answers2

2

You want to use a negated character class here instead of .*?.

The .* inside of your lookahead assertion will match all the way up to the last occurrence of (...) then backtrack consecutively keeping the succession order going.

preg_replace('/\([^)]*\)(?!.*\([^)]*\))/', '', $string);

To simplify this task, just retain everything up until the last occurrence instead.

preg_replace('/.*\K\(.*?\)/', '', $string);
hwnd
  • 69,796
  • 4
  • 95
  • 132
  • Thank you, it works perfectly. Do you mind to explain a little bit more? Why need to use negated character? How it works in this case? Thank you very much. – overshadow Feb 06 '15 at 05:06
  • @hwnd - I tried to use it like this `preg_replace('/(?!\s+as\s+.*)/i', '', '(x as y) as z');` trying to get rid of the final " as..." (expected result = '`(x as y)'` -- but it does not replace anything. Any idea what is wrong? – user9645 Jan 06 '17 at 19:43
0

Youre mistake is using \(.*\) it's replace full substring which begins whith ( and ends whith ). .* - max quantificator, (.*) - min quantificator.

Try to use:

$string = 'hello example (a) hello example (b) (c)'; echo preg_replace('/\((.*)\)$/', '', $string);

winston86
  • 159
  • 1
  • 8