TYPO3  7.6
Regex.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace Symfony\Component\Finder\Expression;
13 
17 class Regex implements ValueInterface
18 {
19  const START_FLAG = '^';
20  const END_FLAG = '$';
21  const BOUNDARY = '~';
22  const JOKER = '.*';
23  const ESCAPING = '\\';
24 
28  private $pattern;
29 
33  private $options;
34 
38  private $startFlag;
39 
43  private $endFlag;
44 
48  private $startJoker;
49 
53  private $endJoker;
54 
62  public static function create($expr)
63  {
64  if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
65  $start = substr($m[1], 0, 1);
66  $end = substr($m[1], -1);
67 
68  if (
69  ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
70  || ($start === '{' && $end === '}')
71  || ($start === '(' && $end === ')')
72  ) {
73  return new self(substr($m[1], 1, -1), $m[2], $end);
74  }
75  }
76 
77  throw new \InvalidArgumentException('Given expression is not a regex.');
78  }
79 
85  public function __construct($pattern, $options = '', $delimiter = null)
86  {
87  if (null !== $delimiter) {
88  // removes delimiter escaping
89  $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
90  }
91 
92  $this->parsePattern($pattern);
93  $this->options = $options;
94  }
95 
99  public function __toString()
100  {
101  return $this->render();
102  }
103 
107  public function render()
108  {
109  return self::BOUNDARY
110  .$this->renderPattern()
111  .self::BOUNDARY
112  .$this->options;
113  }
114 
118  public function renderPattern()
119  {
120  return ($this->startFlag ? self::START_FLAG : '')
121  .($this->startJoker ? self::JOKER : '')
122  .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
123  .($this->endJoker ? self::JOKER : '')
124  .($this->endFlag ? self::END_FLAG : '');
125  }
126 
130  public function isCaseSensitive()
131  {
132  return !$this->hasOption('i');
133  }
134 
138  public function getType()
139  {
140  return Expression::TYPE_REGEX;
141  }
142 
146  public function prepend($expr)
147  {
148  $this->pattern = $expr.$this->pattern;
149 
150  return $this;
151  }
152 
156  public function append($expr)
157  {
158  $this->pattern .= $expr;
159 
160  return $this;
161  }
162 
168  public function hasOption($option)
169  {
170  return false !== strpos($this->options, $option);
171  }
172 
178  public function addOption($option)
179  {
180  if (!$this->hasOption($option)) {
181  $this->options .= $option;
182  }
183 
184  return $this;
185  }
186 
192  public function removeOption($option)
193  {
194  $this->options = str_replace($option, '', $this->options);
195 
196  return $this;
197  }
198 
204  public function setStartFlag($startFlag)
205  {
206  $this->startFlag = $startFlag;
207 
208  return $this;
209  }
210 
214  public function hasStartFlag()
215  {
216  return $this->startFlag;
217  }
218 
224  public function setEndFlag($endFlag)
225  {
226  $this->endFlag = (bool) $endFlag;
227 
228  return $this;
229  }
230 
234  public function hasEndFlag()
235  {
236  return $this->endFlag;
237  }
238 
244  public function setStartJoker($startJoker)
245  {
246  $this->startJoker = $startJoker;
247 
248  return $this;
249  }
250 
254  public function hasStartJoker()
255  {
256  return $this->startJoker;
257  }
258 
264  public function setEndJoker($endJoker)
265  {
266  $this->endJoker = (bool) $endJoker;
267 
268  return $this;
269  }
270 
274  public function hasEndJoker()
275  {
276  return $this->endJoker;
277  }
278 
284  public function replaceJokers($replacement)
285  {
286  $replace = function ($subject) use ($replacement) {
287  $subject = $subject[0];
288  $replace = 0 === substr_count($subject, '\\') % 2;
289 
290  return $replace ? str_replace('.', $replacement, $subject) : $subject;
291  };
292 
293  $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
294 
295  return $this;
296  }
297 
301  private function parsePattern($pattern)
302  {
303  if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
304  $pattern = substr($pattern, 1);
305  }
306 
307  if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
308  $pattern = substr($pattern, 2);
309  }
310 
311  if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
312  $pattern = substr($pattern, 0, -1);
313  }
314 
315  if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
316  $pattern = substr($pattern, 0, -2);
317  }
318 
319  $this->pattern = $pattern;
320  }
321 }