[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * @package s9e\TextFormatter 5 * @copyright Copyright (c) 2010-2019 The s9e Authors 6 * @license http://www.opensource.org/licenses/mit-license.php The MIT License 7 */ 8 namespace s9e\TextFormatter\Configurator\Helpers; 9 use RuntimeException; 10 abstract class RegexpParser 11 { 12 public static function getAllowedCharacterRegexp($regexp) 13 { 14 $def = self::parse($regexp); 15 if (\strpos($def['modifiers'], 'm') !== \false) 16 return '//'; 17 if (\substr($def['regexp'], 0, 1) !== '^' 18 || \substr($def['regexp'], -1) !== '$') 19 return '//'; 20 $def['tokens'][] = [ 21 'pos' => \strlen($def['regexp']), 22 'len' => 0, 23 'type' => 'end' 24 ]; 25 $patterns = []; 26 $literal = ''; 27 $pos = 0; 28 $skipPos = 0; 29 $depth = 0; 30 foreach ($def['tokens'] as $token) 31 { 32 if ($token['type'] === 'option') 33 $skipPos = \max($skipPos, $token['pos'] + $token['len']); 34 if (\strpos($token['type'], 'AssertionStart') !== \false) 35 { 36 $endToken = $def['tokens'][$token['endToken']]; 37 $skipPos = \max($skipPos, $endToken['pos'] + $endToken['len']); 38 } 39 if ($token['pos'] >= $skipPos) 40 { 41 if ($token['type'] === 'characterClass') 42 $patterns[] = '[' . $token['content'] . ']'; 43 if ($token['pos'] > $pos) 44 { 45 $tmp = \substr($def['regexp'], $pos, $token['pos'] - $pos); 46 $literal .= $tmp; 47 if (!$depth) 48 { 49 $tmp = \str_replace('\\\\', '', $tmp); 50 if (\preg_match('/(?<!\\\\)\\|(?!\\^)/', $tmp)) 51 return '//'; 52 if (\preg_match('/(?<![$\\\\])\\|/', $tmp)) 53 return '//'; 54 } 55 } 56 } 57 if (\substr($token['type'], -5) === 'Start') 58 ++$depth; 59 elseif (\substr($token['type'], -3) === 'End') 60 --$depth; 61 $pos = \max($skipPos, $token['pos'] + $token['len']); 62 } 63 if (\preg_match('#(?<!\\\\)(?:\\\\\\\\)*\\.#', $literal)) 64 { 65 if (\strpos($def['modifiers'], 's') !== \false 66 || \strpos($literal, "\n") !== \false) 67 return '//'; 68 $patterns[] = '.'; 69 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)\\.#', '$1', $literal); 70 } 71 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)[*+?]#', '$1', $literal); 72 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)\\{[^}]+\\}#', '$1', $literal); 73 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)\\\\[bBAZzG1-9]#', '$1', $literal); 74 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)[$^|]#', '$1', $literal); 75 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)([-^\\]])#', '$1\\\\$2', $literal); 76 if (\strpos($def['modifiers'], 'D') === \false) 77 $literal .= "\n"; 78 if ($literal !== '') 79 $patterns[] = '[' . $literal . ']'; 80 if (empty($patterns)) 81 return '/^$/D'; 82 $regexp = $def['delimiter'] . \implode('|', $patterns) . $def['delimiter']; 83 if (\strpos($def['modifiers'], 'i') !== \false) 84 $regexp .= 'i'; 85 if (\strpos($def['modifiers'], 'u') !== \false) 86 $regexp .= 'u'; 87 return $regexp; 88 } 89 public static function getCaptureNames($regexp) 90 { 91 $map = ['']; 92 $regexpInfo = self::parse($regexp); 93 foreach ($regexpInfo['tokens'] as $tok) 94 if ($tok['type'] === 'capturingSubpatternStart') 95 $map[] = (isset($tok['name'])) ? $tok['name'] : ''; 96 return $map; 97 } 98 public static function parse($regexp) 99 { 100 if (!\preg_match('#^(.)(.*?)\\1([a-zA-Z]*)$#Ds', $regexp, $m)) 101 throw new RuntimeException('Could not parse regexp delimiters'); 102 $ret = [ 103 'delimiter' => $m[1], 104 'modifiers' => $m[3], 105 'regexp' => $m[2], 106 'tokens' => [] 107 ]; 108 $regexp = $m[2]; 109 $openSubpatterns = []; 110 $pos = 0; 111 $regexpLen = \strlen($regexp); 112 while ($pos < $regexpLen) 113 { 114 switch ($regexp[$pos]) 115 { 116 case '\\': 117 $pos += 2; 118 break; 119 case '[': 120 if (!\preg_match('#\\[(.*?(?<!\\\\)(?:\\\\\\\\)*+)\\]((?:[+*][+?]?|\\?)?)#A', $regexp, $m, 0, $pos)) 121 throw new RuntimeException('Could not find matching bracket from pos ' . $pos); 122 $ret['tokens'][] = [ 123 'pos' => $pos, 124 'len' => \strlen($m[0]), 125 'type' => 'characterClass', 126 'content' => $m[1], 127 'quantifiers' => $m[2] 128 ]; 129 $pos += \strlen($m[0]); 130 break; 131 case '(': 132 if (\preg_match('#\\(\\?([a-z]*)\\)#iA', $regexp, $m, 0, $pos)) 133 { 134 $ret['tokens'][] = [ 135 'pos' => $pos, 136 'len' => \strlen($m[0]), 137 'type' => 'option', 138 'options' => $m[1] 139 ]; 140 $pos += \strlen($m[0]); 141 break; 142 } 143 if (\preg_match("#(?J)\\(\\?(?:P?<(?<name>[a-z_0-9]+)>|'(?<name>[a-z_0-9]+)')#A", $regexp, $m, \PREG_OFFSET_CAPTURE, $pos)) 144 { 145 $tok = [ 146 'pos' => $pos, 147 'len' => \strlen($m[0][0]), 148 'type' => 'capturingSubpatternStart', 149 'name' => $m['name'][0] 150 ]; 151 $pos += \strlen($m[0][0]); 152 } 153 elseif (\preg_match('#\\(\\?([a-z]*):#iA', $regexp, $m, 0, $pos)) 154 { 155 $tok = [ 156 'pos' => $pos, 157 'len' => \strlen($m[0]), 158 'type' => 'nonCapturingSubpatternStart', 159 'options' => $m[1] 160 ]; 161 $pos += \strlen($m[0]); 162 } 163 elseif (\preg_match('#\\(\\?>#iA', $regexp, $m, 0, $pos)) 164 { 165 $tok = [ 166 'pos' => $pos, 167 'len' => \strlen($m[0]), 168 'type' => 'nonCapturingSubpatternStart', 169 'subtype' => 'atomic' 170 ]; 171 $pos += \strlen($m[0]); 172 } 173 elseif (\preg_match('#\\(\\?(<?[!=])#A', $regexp, $m, 0, $pos)) 174 { 175 $assertions = [ 176 '=' => 'lookahead', 177 '<=' => 'lookbehind', 178 '!' => 'negativeLookahead', 179 '<!' => 'negativeLookbehind' 180 ]; 181 $tok = [ 182 'pos' => $pos, 183 'len' => \strlen($m[0]), 184 'type' => $assertions[$m[1]] . 'AssertionStart' 185 ]; 186 $pos += \strlen($m[0]); 187 } 188 elseif (\preg_match('#\\(\\?#A', $regexp, $m, 0, $pos)) 189 throw new RuntimeException('Unsupported subpattern type at pos ' . $pos); 190 else 191 { 192 $tok = [ 193 'pos' => $pos, 194 'len' => 1, 195 'type' => 'capturingSubpatternStart' 196 ]; 197 ++$pos; 198 } 199 $openSubpatterns[] = \count($ret['tokens']); 200 $ret['tokens'][] = $tok; 201 break; 202 case ')': 203 if (empty($openSubpatterns)) 204 throw new RuntimeException('Could not find matching pattern start for right parenthesis at pos ' . $pos); 205 $k = \array_pop($openSubpatterns); 206 $startToken =& $ret['tokens'][$k]; 207 $startToken['endToken'] = \count($ret['tokens']); 208 $startToken['content'] = \substr( 209 $regexp, 210 $startToken['pos'] + $startToken['len'], 211 $pos - ($startToken['pos'] + $startToken['len']) 212 ); 213 $spn = \strspn($regexp, '+*?', 1 + $pos); 214 $quantifiers = \substr($regexp, 1 + $pos, $spn); 215 $ret['tokens'][] = [ 216 'pos' => $pos, 217 'len' => 1 + $spn, 218 'type' => \substr($startToken['type'], 0, -5) . 'End', 219 'quantifiers' => $quantifiers 220 ]; 221 unset($startToken); 222 $pos += 1 + $spn; 223 break; 224 default: 225 ++$pos; 226 } 227 } 228 if (!empty($openSubpatterns)) 229 throw new RuntimeException('Could not find matching pattern end for left parenthesis at pos ' . $ret['tokens'][$openSubpatterns[0]]['pos']); 230 return $ret; 231 } 232 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |