0

我需要一个 php 中的正则表达式,它允许以下内容:

这是给定的示例
1. aaa aaa{bb b {c cc}{d dd}e ee}xxx
2. 123{asd{asd{asd{asd}asd}}asd}qwe

输出将是:
1. {bb b {c cc}{d dd}e ee}
2. {asd{asd{asd{asd}asd}}asd}

我试过这个但不起作用

preg_match_all('/{(.*?)}/', $resonse, $matches);

它基本上摆脱了主要花括号之外的任何东西,即使里面有花括号。我真的需要你的帮助。非常感谢。

4

5 回答 5

3

您将需要 PCRE 的递归功能来执行此操作。

<?php
$pattern = '!
  { # patterns start with curly brace
      (?:           # ?: means that this is only for grouping, not for capturing
                    # the { } contain 
        [^{}]*      # not-curly-braces-characters
      |             # or
        (?R)        # this pattern again, i.e. {^[{}] | (?R) } again
      )*
  } # patterns ends with curly brace
!x';

foreach( array('aaa aaa{bb b {c cc}{d dd}e ee}xxx', '123{asd{asd{asd{asd}asd}}asd}qwe') as $subject ) {
    echo "\n$subject: ";
    if ( preg_match($pattern, $subject, $m) ) {
        echo $m[0];
    }
    else {
        echo '--no match--';
    }
}

印刷

aaa aaa{bb b {c cc}{d dd}e ee}xxx: {bb b {c cc}{d dd}e ee}
123{asd{asd{asd{asd}asd}}asd}qwe: {asd{asd{asd{asd}asd}}asd}
于 2012-08-03T07:17:21.497 回答
2

你根本不需要正则表达式:

$str = 'aaa aaa{bb b {c cc}{d dd}e ee}xxx';

$replace = substr(substr($str, 0, strrpos($str, '}') + 1), strpos($str, '{'));

echo $replace; // displays "{bb b {c cc}{d dd}e ee}"

如果你对这段代码进行基准测试,它可能会比正则表达式快得多。你不应该用复杂的东西来做这么简单的事情。

我想你可能想为每个字符串匹配多个结果。在这种情况下,我可能仍然有一个不依赖任何模块的更快的解决方案:

$str = 'aaa aaa{bb b {c cc}{d dd}e ee}xxxaaa qaaa{bb b {cqwe cc}{d cdd}e qweee}xxx';
$array = str_split($str);
$opens = 0;
$result = '';

$results = array();

for($i = 0; $i < count($array); $i++) {
    if($array[$i] === '{') {
        $opens++;
    } else if($array[$i] === '}' && $opens > 0) {
        $opens--;
    }

    if($opens > 0) $result .= $array[$i];

    if($opens === 0 && strlen($result) > 0) {
        $results[] = $result . '}';
        $result = '';
    }
}

print_r($results);

/*
results:
Array
(
    [0] => {bb b {c cc}{d dd}e ee}
    [1] => {bb b {cqwe cc}{d cdd}e qweee}
)

*/
于 2012-08-03T07:21:29.513 回答
0
<?php
$str = "abc{def{ghi{jkl}mno{pqr}st}uvw}xyz" ;

$str = preg_match("#\{((?>[^\{\}]+)|(?R))*\}#x", $str, $matches, PREG_OFFSET_CAPTURE, 3);

print_r($matches);
?>
于 2012-08-03T07:20:10.450 回答
0

也许这会做到:preg_replace('/(^[^{]*)|([^}]*$)/', '', 'aaa aaa{bb b {c cc}{d dd}e ee}xxx');

于 2012-08-03T07:20:21.050 回答
0

这真的是正则表达式的工作吗?{通过查找 first和 last来获取您想要的子字符串似乎更容易}。例如,这个:

$str = "abc {kjlj { jkljlkj } ljkj } kljlj";

$start = strpos($str, '{');  # First {
$end = strrpos($str, '}');   # Last }

$section = substr($str, $start, $end - $start + 1);
echo $section;  # => "{kjlj { jkljlkj } ljkj }"
于 2012-08-03T07:32:24.600 回答