Geoff
Geoff

Reputation: 1007

php regexp removing text

If I have a string of the form:

$text='remove1  (keep1) remove2 (keep2) remove3';

Using the response

https://stackoverflow.com/a/5293343/1154853

$re = '/[^()]*+(\((?:[^()]++|(?1))*\))[^()]*+/';
$text = preg_replace($re, '$1', $text);

I get

(keep1)(keep2)

If I want to go from

$text='remove1  {keep1} remove2 {keep2} remove3';

to

{keep1}{keep2}

that is I want to change the delimiters, how do I change the given regular expression? I tried all sorts of combinations of changing ( to { but I couldn't get it to work. I find these reg exp pretty tough!

Upvotes: 1

Views: 99

Answers (3)

Tomalak
Tomalak

Reputation: 338158

For parentheses (), you could use:

$re = '/(?:^|(?<=\)))[^(]+/';
$text = preg_replace($re, '', $text);

EDIT For braces {}, use this variant:

$re = '/(?:^|(?<=\}))[^{]+/';
$text = preg_replace($re, '', $text);

Note that these will fail - as all regex does - for nested structures.

Explanation

(?:        # non-capturing group start
  ^        #   start-of-string
  |        #   or...
  (?<=\})  #   look-behind: a position preceded by a } closing brace
)          # end non-capturing group
[^{]+      # any character except an opening brace, multiple times

The non-capturing group fixes the start of the match behind a closing brace or at the start of the string. The [^{]+ matches every character up to the next brace. Effectively this matches everything in-between {words}.

See it: http://rubular.com/r/1Sp72TbHIi

EDIT #2 Of course, thinking less complicated, this would also work:

$re = '/((?:\\\w+)?\{[^}]*\})/';
$text = preg_replace($re, '$1', $text);

http://rubular.com/r/rPLMbCLbcq

Upvotes: 0

Ethan
Ethan

Reputation: 902

Try this:

$re = '/[^{}]*+(\{(?:[^{}]++|(?1))*\})[^{}]*+/';
$text = preg_replace($re, '$1', $text);

Upvotes: 0

nickb
nickb

Reputation: 59699

You need to escape the curly brackets:

$re = '/[^()]*+(\((?:[^()]++|(?1))*\))[^()]*+/';
          ^^     ^     ^^           ^   ^^
                 Esc                Esc

The markings are where your delimiters are, only two need to be escaped with slashes. I believe this will work:

$re = '/[^{}]*+(\{(?:[^{}]++|(?1))*\})[^{}]*+/';

Upvotes: 1

Related Questions