正如@Sniffer說,我做了一個解析器。這很雜亂,但是做這個工作。它是模板系統類的一部分。 $this->rendered
是一個正在被解析的字符串。
const COND_START = '((';
const COND_END = '))';
const COND_SEP = '?';
const COND_NOT = '!';
private function parseConditionals()
{
for (
$i=0,
$level=0,
$levelstart=array(0=>0),
$levelseparator=array(0=>0),
$levelname=array(0=>'__main__');
$i < strlen($this->rendered);
) {
$startpos = strpos($this->rendered, self::COND_START, $i);
$seppos = strpos($this->rendered, self::COND_SEP, $i);
$endpos = strpos($this->rendered, self::COND_END, $i);
if (($startpos === FALSE) && ($endpos === FALSE)) {
$i = strlen($this->rendered);
} elseif (($startpos !== FALSE) && $startpos < $endpos) {
if ($seppos < $endpos) {
$level++;
$levelstart[$level] = $startpos;
$levelseparator[$level] = $seppos;
$levelname[$level] = substr(
$this->rendered,
$startpos+strlen(self::COND_START),
$seppos-$startpos-strlen(self::COND_START)
);
$i = $seppos + strlen(self::COND_SEP);
} else {
$i = $startpos + strlen(self::COND_START);
}
} else {
$originallen = strlen($this->rendered);
if ($level > 0) {
$not = false;
if (strpos($levelname[$level], self::COND_NOT) === 0) {
$levelname[$level] = substr($levelname[$level], strlen(self::COND_SEP));
$not = true;
}
if (
!$this->get($levelname[$level]) == $not
) {
$this->rendered = substr_replace(
$this->rendered,
'',
$endpos,
strlen(self::COND_END)
);
$this->rendered = substr_replace(
$this->rendered,
'',
$levelstart[$level],
$levelseparator[$level]-$levelstart[$level]+strlen(self::COND_SEP)
);
} else {
$this->rendered = substr_replace(
$this->rendered,
'',
$levelstart[$level],
$endpos-$levelstart[$level]+strlen(self::COND_END)
);
}
$level--;
}
$i = $endpos + strlen(self::COND_END);
$i += strlen($this->rendered)-$originallen;
}
}
}
我需要捕獲它們。另外你的模式不允許在值組中使用'()'字符,這不是我想要的。 – Arrvi