Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
RegexpParser.php
001 <?php
002
003 /*
004 * @package s9e\TextFormatter
005 * @copyright Copyright (c) 2010-2016 The s9e Authors
006 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
007 */
008 namespace s9e\TextFormatter\Configurator\Helpers;
009 use RuntimeException;
010 abstract class RegexpParser
011 {
012 public static function getAllowedCharacterRegexp($regexp)
013 {
014 $def = self::parse($regexp);
015 if (\strpos($def['modifiers'], 'm') !== \false)
016 return '//';
017 if (\substr($def['regexp'], 0, 1) !== '^'
018 || \substr($def['regexp'], -1) !== '$')
019 return '//';
020 $def['tokens'][] = array(
021 'pos' => \strlen($def['regexp']),
022 'len' => 0,
023 'type' => 'end'
024 );
025 $patterns = array();
026 $literal = '';
027 $pos = 0;
028 $skipPos = 0;
029 $depth = 0;
030 foreach ($def['tokens'] as $token)
031 {
032 if ($token['type'] === 'option')
033 $skipPos = \max($skipPos, $token['pos'] + $token['len']);
034 if (\strpos($token['type'], 'AssertionStart') !== \false)
035 {
036 $endToken = $def['tokens'][$token['endToken']];
037 $skipPos = \max($skipPos, $endToken['pos'] + $endToken['len']);
038 }
039 if ($token['pos'] >= $skipPos)
040 {
041 if ($token['type'] === 'characterClass')
042 $patterns[] = '[' . $token['content'] . ']';
043 if ($token['pos'] > $pos)
044 {
045 $tmp = \substr($def['regexp'], $pos, $token['pos'] - $pos);
046 $literal .= $tmp;
047 if (!$depth)
048 {
049 $tmp = \str_replace('\\\\', '', $tmp);
050 if (\preg_match('/(?<!\\\\)\\|(?!\\^)/', $tmp))
051 return '//';
052 if (\preg_match('/(?<![$\\\\])\\|/', $tmp))
053 return '//';
054 }
055 }
056 }
057 if (\substr($token['type'], -5) === 'Start')
058 ++$depth;
059 elseif (\substr($token['type'], -3) === 'End')
060 --$depth;
061 $pos = \max($skipPos, $token['pos'] + $token['len']);
062 }
063 if (\preg_match('#(?<!\\\\)(?:\\\\\\\\)*\\.#', $literal))
064 {
065 if (\strpos($def['modifiers'], 's') !== \false
066 || \strpos($literal, "\n") !== \false)
067 return '//';
068 $patterns[] = '.';
069 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)\\.#', '$1', $literal);
070 }
071 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)[*+?]#', '$1', $literal);
072 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)\\{[^}]+\\}#', '$1', $literal);
073 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)\\\\[bBAZzG1-9]#', '$1', $literal);
074 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)[$^|]#', '$1', $literal);
075 $literal = \preg_replace('#(?<!\\\\)((?:\\\\\\\\)*)([-^\\]])#', '$1\\\\$2', $literal);
076 if (\strpos($def['modifiers'], 'D') === \false)
077 $literal .= "\n";
078 if ($literal !== '')
079 $patterns[] = '[' . $literal . ']';
080 if (empty($patterns))
081 return '/^$/D';
082 $regexp = $def['delimiter'] . \implode('|', $patterns) . $def['delimiter'];
083 if (\strpos($def['modifiers'], 'i') !== \false)
084 $regexp .= 'i';
085 if (\strpos($def['modifiers'], 'u') !== \false)
086 $regexp .= 'u';
087 return $regexp;
088 }
089 public static function getCaptureNames($regexp)
090 {
091 $map = array('');
092 $regexpInfo = self::parse($regexp);
093 foreach ($regexpInfo['tokens'] as $tok)
094 if ($tok['type'] === 'capturingSubpatternStart')
095 $map[] = (isset($tok['name'])) ? $tok['name'] : '';
096 return $map;
097 }
098 public static function parse($regexp)
099 {
100 if (!\preg_match('#^(.)(.*?)\\1([a-zA-Z]*)$#Ds', $regexp, $m))
101 throw new RuntimeException('Could not parse regexp delimiters');
102 $ret = array(
103 'delimiter' => $m[1],
104 'modifiers' => $m[3],
105 'regexp' => $m[2],
106 'tokens' => array()
107 );
108 $regexp = $m[2];
109 $openSubpatterns = array();
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('#\\[(.*?(?<!\\\\)(?:\\\\\\\\)*+)\\]((?:[+*][+?]?|\\?)?)#', $regexp, $m, 0, $pos))
121 throw new RuntimeException('Could not find matching bracket from pos ' . $pos);
122 $ret['tokens'][] = array(
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]*)\\)#i', $regexp, $m, 0, $pos))
133 {
134 $ret['tokens'][] = array(
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 = array(
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 = array(
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 = array(
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 = array(
176 '=' => 'lookahead',
177 '<=' => 'lookbehind',
178 '!' => 'negativeLookahead',
179 '<!' => 'negativeLookbehind'
180 );
181 $tok = array(
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 = array(
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'][] = array(
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 }