Keys →
Functions ↓
function findBalancer ( $str, $pos=0, $flags=0 ) {#-k parse string#- Find the position of the balancing element to $str[$pos]. It also recognizes quotes as balancers.#- <({['`" are balanced by ">)}]'`" respectively.#- This assumes caller is not inside a comment or quote as of $str[$pos].#- Nesting is recognized & processed:#- "(x(),1)" will return 6, not 3.#- Super-nesting is default: if other openers are found, they must be closed before finishing.#- "(x(<'123)'>),3)" will return 14, because the ")" at 8 was in a quote, the ")" at 11 closed the inner call.#-p $str - req - string to search#-p $pos - opt - position to start looking in $str (default 0)#-p $flags - opt - .<15> = 0 (default) direction to scan#-p - = 1 backwards (not yet implemented)#-p - .<14> = 0 manage supernesting#-p - = 1 simple nesting#-p - ret - offset of balancing element or error#- error -1 $pos beyond eos#- -2 $str[$pos] not an opening balancer#- -3 didn't find balancer b4 eos#- -4 didn't find start of group b4 bos#- -5 not implemented#-r Supercedes: skipOver & skipPast#-f To be fixed: add reverse search#-d 2/24/21 - added $f = "<({['`" . '"'; $t = ">)}]'`" . '"'; if ((!strlen($str)) or ($pos < 0) or ($pos >= strlen($str))) return -1; $m = strpos(' '.$f,$str[$pos]); # look for the opening char in legit openers if (!$m) return -2; $o = $f[--$m]; # opener char $c = $t[$m]; # closer char if ($flags & BIT15) { # reverse search return -5; } else { if ($flags & BIT14) { # simple nesting $p = $pos+1; $o1 = -1; $c1 = 0; while ($o1 < $c1) { $o1 = strpos(' '.substr($str,$p),$o); # look for next opener $c1 = strpos(' '.substr($str,$p),$c); # look for next closer if (!$c1) return -3; if (!$o1) return $p+$c1-1; if ($c1<$o1) return $p+$c1-1; # there was an opener, but it was beyond the closer if ($o1<$c1) $p=$p+$c1+1; # there's another opener before the closer } } else { # super-nesting for ($i=$pos;$i<strlen($str);$i++) { $x = strpos(' '.$f,$str[$i]); $y = strpos(' '.$t,$str[$i]); if ($x && ($x == $y)) { # Got a ' or a "; incr $i until we find its match $z = $str[$i]; $i++; while (($i<strlen($str)) && ($str[$i] <> $z)) $i++; if ($i >= strlen($str)) return -3; } elseif ($x) { # starting a new nest $nest++; $xLast .= $x; # push $x onto stack } elseif ($y && ($y == right($xLast,1))) { # coming out of an existing nest IFF this closer matches the latest opener $xLast = deRight($xLast,1); # pop $x from stack $nest--; if (($nest == 0) && ($str[$i] == $c)) return $i; } } return -3; } } return -5; }?>