Reputation: 3323
By now i'm using regex: '/{(.*?)}/'
to get everything inside curly barackets in strings like: 'abc {get me} def {and get me}'
which works fine.
Now i'm looking for a way to exclude brackets, which are surrounded by brackets themselves. The string should be self-explanatory: 'abc {get me {!but not me!}} def {and get {!but not me again!} me} ghi'
.
The following code should illustrate my needs...
<?php
$regex = '/{(.*?)}/';
$string = 'abc {get me {!but not me!}} def {and get {!but not me again!} me} ghi';
preg_match_all( $regex, $string, $matches );
print_r( $matches[1] );
?>
prints:
Array
(
[0] => get me {!but not me!
[1] => and get {!but not me again!
)
but should be:
Array
(
[0] => get me {!but not me!}
[1] => and get {!but not me again!} me
)
Until now i was not able to find a solution via Google and looking forward to get one at SO.
regards
EDIT: Actually a very similar question was asked and answered on SO. But if you are not familiar with regex it's really hard to change from wrapper (...) to {...}. So you can not simply take the one pattern given by the answer (see link above) and search-replace all '(' & ')' with '{' & '}'. You really have to understand what's going on there.
But if you understand this pattern enough to customize it you probably would be able to write it on your own...
Upvotes: 1
Views: 103
Reputation: 3323
$delimiter_wrap = '~';
$delimiter_left = '{';/* put YOUR left delimiter here. */
$delimiter_right = '}';/* put YOUR right delimiter here. */
$delimiter_left = preg_quote( $delimiter_left, $delimiter_wrap );
$delimiter_right = preg_quote( $delimiter_right, $delimiter_wrap );
$pattern = $delimiter_wrap . $delimiter_left
. '((?:[^' . $delimiter_left . $delimiter_right . ']++|(?R))*)'
. $delimiter_right . $delimiter_wrap;
/* Now you can use the generated pattern. */
preg_match_all( $pattern, $subject, $matches );
Credits: Thank you @Wiktor Stribiżew who wrote the answer i accepted...
Upvotes: 0
Reputation: 627517
You need a recursive regex with a capturing group that would capture the contents inside the curly braces:
{((?:[^{}]++|(?R))*)}
Explanation:
{
- a literal {
(in PHP PCRE, you do not need to escape this character)(
- Start of the capturing group 1
(?:[^{}]++|(?R))*
- zero or more sequences (see (?:...)*
) of 1+ characters other than {
and }
(see [^{}]++
) or the whole pattern ((?R)
is a placeholder for the whole pattern, like (?0)
subroutine call))
- end of Group 1}
- closing literal }
See the regex demo and the PHP demo:
$re = '~{((?:[^{}]++|(?R))*)}~';
$str = "abc {get me {!but not me!}} def {and get {!but not me again!} me} ghi";
preg_match_all($re, $str, $matches);
print_r($matches[1]);
Upvotes: 2