src/MvcCore/Ext/Debugs/Tracys/RoutingPanel.php
protected function completeMatchingBracketsPositions ($str, $begin, $end) {
		$result = [];
		$i = 0;
		$l = mb_strlen($str);
		$matches = [];
		while ($i < $l) {
			$beginPos = mb_strpos($str, $begin, $i);
			$endPos = mb_strpos($str, $end, $i);
			$beginContained = $beginPos !== FALSE;
			$endContained = $endPos !== FALSE;
			if ($beginContained && $endContained) {
				if ($beginPos < $endPos) {
					$matches[] = [$begin, $beginPos];
					$i = $beginPos + 1;
				} else {
					$matches[] = [$end, $endPos];
					$i = $endPos + 1;
				}
			} else if ($beginContained) {
				$matches[] = [$begin, $beginPos];
				$i = $beginPos + 1;
			} else if ($endContained) {
				$matches[] = [$end, $endPos];
				$i = $endPos + 1;
			} else {
				break;
			}
		}
		if ($matches) {
			$level = 0;
			$groupBegin = -1;
			$paramLevel = 0;
			foreach ($matches as $item) {
				list($itemChar, $itemPos) = $item;
				$backSlashesCnt = 0;
				$backSlashPos = $itemPos - 1;
				while ($backSlashPos > -1 && true) {
					$prevChar = mb_substr($str, $backSlashPos, 1);
					if ($prevChar == '\\') {
						$backSlashesCnt += 1;
						$backSlashPos -= 1;
					} else {
						break;
					}
				}
				if (
					$backSlashesCnt === 0 || (
					($backSlashesCnt > 0 && $backSlashesCnt % 2 === 0)
				)) {
					if ($itemChar == $begin) {
						if ($begin == '(') {
							$itemCharNext = mb_substr($str, $itemPos + 1, 1);
							if ($itemCharNext !== '?') {
								$level += 1;
								continue;
							}
						}
						$paramLevel = $level;
						$groupBegin = $itemPos;
						$level += 1;
					} else {
						$level -= 1;
						if ($level === $paramLevel && $groupBegin > -1) {
							$result[] = [
								mb_substr($str, $groupBegin, $itemPos - $groupBegin + 1),
								$groupBegin,
								$itemPos
							];
						}
					}
				}
			}
		}
		return $result;
	}
protected function completeMatchingBracketsPositions ($str, $begin, $end) {
		$result = [];
		$i = 0;
		$l = mb_strlen($str);
		$matches = [];
		while ($i < $l) {
			$beginPos = mb_strpos($str, $begin, $i);
			$endPos = mb_strpos($str, $end, $i);
			$beginContained = $beginPos !== FALSE;
			$endContained = $endPos !== FALSE;
			if ($beginContained && $endContained) {
				if ($beginPos < $endPos) {
					$matches[] = [$begin, $beginPos];
					$i = $beginPos + 1;
				} else {
					$matches[] = [$end, $endPos];
					$i = $endPos + 1;
				}
			} else if ($beginContained) {
				$matches[] = [$begin, $beginPos];
				$i = $beginPos + 1;
			} else if ($endContained) {
				$matches[] = [$end, $endPos];
				$i = $endPos + 1;
			} else {
				break;
			}
		}
		if ($matches) {
			$level = 0;
			$groupBegin = -1;
			$paramLevel = 0;
			foreach ($matches as $item) {
				list($itemChar, $itemPos) = $item;
				$backSlashesCnt = 0;
				$backSlashPos = $itemPos - 1;
				while ($backSlashPos > -1 && true) {
					$prevChar = mb_substr($str, $backSlashPos, 1);
					if ($prevChar == '\\') {
						$backSlashesCnt += 1;
						$backSlashPos -= 1;
					} else {
						break;
					}
				}
				if (
					$backSlashesCnt === 0 || (
					($backSlashesCnt > 0 && $backSlashesCnt % 2 === 0)
				)) {
					if ($itemChar == $begin) {
						if ($begin == '(') {
							$itemCharNext = mb_substr($str, $itemPos + 1, 1);
							if ($itemCharNext !== '?') {
								$level += 1;
								continue;
							}
						}
						$paramLevel = $level;
						$groupBegin = $itemPos;
						$level += 1;
					} else {
						$level -= 1;
						if ($level === $paramLevel && $groupBegin > -1) {
							$result[] = [
								mb_substr($str, $groupBegin, $itemPos - $groupBegin + 1),
								$groupBegin,
								$itemPos
							];
						}
					}
				}
			}
		}
		return $result;
	}
Complete collection with first level matching brackets,
info about substrings between them and their opening and closing
positions to complete task with character group colouring in
local method $this->completeFormatedPatternOrReverseCharGroups().
@param string $str	string to search brackets in
@param string $begin	opening bracket char
@param string $end	closing bracket char
@return array[]