PHP, preg_match:如何在两个字符之间获得字符串,比如大括号,子标记在大括号中



如果我有一个像这样的字符串:

$str = "Some {translate:text} with some {if:{isCool}?{translate:cool}|{translate:uncool}} features";

…我希望得到以下结果:

array (
  0 => 'translate:text',
  1 => 'if:{isCool}?{translate:cool}|{translate:uncool}',
)

我已经有这个函数,但我相信它可以简化它与preg_match(_all)?

define('STR_START','{');
define('STR_END','}');
function getMarkers($str, &$arr = array()) {
    if(strpos($str,STR_START)) {
        list($trash,$str) = explode(STR_START,$str, 2);
        unset($trash);
        $startPos = 0;
        $endPos = 0;
        do {
            $strStartPos = strpos($str,STR_START,$startPos);
            $strEndPos = strpos($str,STR_END,$endPos);
            $startPos = $strStartPos + 1;
            $endPos = $strEndPos + 1;
        } while($strStartPos !== false && $strStartPos < $strEndPos);
        $arr[] = substr($str,0,$strEndPos);
        getMarkers(substr($str,$strEndPos+1),$arr);
    }
    return $arr;
}

我已经尝试了以下方法,但它对子标记的效果不太好。

preg_match_all('/{(.*?)}/',"Some {translate:text} with some {if:{isCool}?{translate:cool}|{translate:uncool}} features", $matches);
var_export($matches[1]);
array (
  0 => 'translate:text',
  1 => 'if:{isCool',
  2 => 'translate:cool',
  3 => 'translate:uncool',
)

是否有可能调整上述模式以获得正确的结果?

array (
  0 => 'translate:text',
  1 => 'if:{isCool}?{translate:cool}|{translate:uncool}',
)

您需要使用递归模式,例如:

$pattern = '~{((?>[^{}]++|(?R))*)}~';

其中(?R)代表所有模式(整个模式在自身内部重复)

最新更新