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.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

RegexpParser.php

Zuletzt modifiziert: 09.10.2024, 12:58 - Dateigröße: 6.97 KiB


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  }