Reputation: 1007
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
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
Reputation: 902
Try this:
$re = '/[^{}]*+(\{(?:[^{}]++|(?1))*\})[^{}]*+/';
$text = preg_replace($re, '$1', $text);
Upvotes: 0
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