The basic algorithm for this is similar to the following
- for each sequence
{ no-braces-here } , put it in the buffer and replace it with a magic number identifying its position in the buffer - repeat (1) until more sequences are found
- for each entry in the buffer - if it contains magic numbers, replace each number with the corresponding line from the buffer.
- The buffer is what we are looking for.
in 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; } }
Test
$p = new Parser; $a = $p->run("just text { foo and { bar and { baz } and { quux } } hello! } ??"); print_r($a);
result
Array ( [0] => { baz } [1] => { quux } [2] => { bar and { baz } and { quux } } [3] => { foo and { bar and { baz } and { quux } } hello! } )
let me know if you have any questions.
source share