如果我有如下字符串:
$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}',
)
答案 0 :(得分:1)
您需要使用递归模式,例如:
$pattern = '~{((?>[^{}]++|(?R))*)}~';
(?R)
代表所有模式(整个模式在其内部重复)