このための基本的なアルゴリズムは次のようなものです
- すべてのシーケンス
{ no-braces-here }
について、それをバッファに入れ、バッファ内の位置を識別するマジック ナンバーに置き換えます
- シーケンスが見つからなくなるまで (1) を繰り返す
- バッファ内のすべてのエントリに対して - マジック ナンバーが含まれている場合、各数値をバッファ内の対応する文字列に置き換えます。
- バッファは私たちが探しているものです
PHPで
class Parser
{
var $buf = array();
function put_to_buf($x) {
$this->buf[] = $x[0];
return '@' . (count($this->buf) - 1) . '@';
}
function get_from_buf($x) {
return $this->buf[intval($x[1])];
}
function replace_all($re, $str, $callback) {
while(preg_match($re, $str))
$str = preg_replace_callback($re, array($this, $callback), $str);
return $str;
}
function run($text) {
$this->replace_all('~{[^{}]*}~', $text, 'put_to_buf');
foreach($this->buf as &$s)
$s = $this->replace_all('~@(\d+)@~', $s, 'get_from_buf');
return $this->buf;
}
}
テスト
$p = new Parser;
$a = $p->run("just text { foo and { bar and { baz } and { quux } } hello! } ??");
print_r($a);
結果
Array
(
[0] => { baz }
[1] => { quux }
[2] => { bar and { baz } and { quux } }
[3] => { foo and { bar and { baz } and { quux } } hello! }
)
ご不明な点がございましたら、お知らせください。