Yaffs site version 1.1
[yaffs-website] / vendor / symfony / finder / Expression / Regex.php
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
14 @trigger_error('The '.__NAMESPACE__.'\Regex class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
15
16 /**
17  * @author Jean-François Simon <contact@jfsimon.fr>
18  */
19 class Regex implements ValueInterface
20 {
21     const START_FLAG = '^';
22     const END_FLAG = '$';
23     const BOUNDARY = '~';
24     const JOKER = '.*';
25     const ESCAPING = '\\';
26
27     /**
28      * @var string
29      */
30     private $pattern;
31
32     /**
33      * @var array
34      */
35     private $options;
36
37     /**
38      * @var bool
39      */
40     private $startFlag;
41
42     /**
43      * @var bool
44      */
45     private $endFlag;
46
47     /**
48      * @var bool
49      */
50     private $startJoker;
51
52     /**
53      * @var bool
54      */
55     private $endJoker;
56
57     /**
58      * @param string $expr
59      *
60      * @return self
61      *
62      * @throws \InvalidArgumentException
63      */
64     public static function create($expr)
65     {
66         if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
67             $start = substr($m[1], 0, 1);
68             $end = substr($m[1], -1);
69
70             if (
71                 ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
72                 || ($start === '{' && $end === '}')
73                 || ($start === '(' && $end === ')')
74             ) {
75                 return new self(substr($m[1], 1, -1), $m[2], $end);
76             }
77         }
78
79         throw new \InvalidArgumentException('Given expression is not a regex.');
80     }
81
82     /**
83      * @param string $pattern
84      * @param string $options
85      * @param string $delimiter
86      */
87     public function __construct($pattern, $options = '', $delimiter = null)
88     {
89         if (null !== $delimiter) {
90             // removes delimiter escaping
91             $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
92         }
93
94         $this->parsePattern($pattern);
95         $this->options = $options;
96     }
97
98     /**
99      * @return string
100      */
101     public function __toString()
102     {
103         return $this->render();
104     }
105
106     /**
107      * {@inheritdoc}
108      */
109     public function render()
110     {
111         return self::BOUNDARY
112             .$this->renderPattern()
113             .self::BOUNDARY
114             .$this->options;
115     }
116
117     /**
118      * {@inheritdoc}
119      */
120     public function renderPattern()
121     {
122         return ($this->startFlag ? self::START_FLAG : '')
123             .($this->startJoker ? self::JOKER : '')
124             .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
125             .($this->endJoker ? self::JOKER : '')
126             .($this->endFlag ? self::END_FLAG : '');
127     }
128
129     /**
130      * {@inheritdoc}
131      */
132     public function isCaseSensitive()
133     {
134         return !$this->hasOption('i');
135     }
136
137     /**
138      * {@inheritdoc}
139      */
140     public function getType()
141     {
142         return Expression::TYPE_REGEX;
143     }
144
145     /**
146      * {@inheritdoc}
147      */
148     public function prepend($expr)
149     {
150         $this->pattern = $expr.$this->pattern;
151
152         return $this;
153     }
154
155     /**
156      * {@inheritdoc}
157      */
158     public function append($expr)
159     {
160         $this->pattern .= $expr;
161
162         return $this;
163     }
164
165     /**
166      * @param string $option
167      *
168      * @return bool
169      */
170     public function hasOption($option)
171     {
172         return false !== strpos($this->options, $option);
173     }
174
175     /**
176      * @param string $option
177      *
178      * @return $this
179      */
180     public function addOption($option)
181     {
182         if (!$this->hasOption($option)) {
183             $this->options .= $option;
184         }
185
186         return $this;
187     }
188
189     /**
190      * @param string $option
191      *
192      * @return $this
193      */
194     public function removeOption($option)
195     {
196         $this->options = str_replace($option, '', $this->options);
197
198         return $this;
199     }
200
201     /**
202      * @param bool $startFlag
203      *
204      * @return $this
205      */
206     public function setStartFlag($startFlag)
207     {
208         $this->startFlag = $startFlag;
209
210         return $this;
211     }
212
213     /**
214      * @return bool
215      */
216     public function hasStartFlag()
217     {
218         return $this->startFlag;
219     }
220
221     /**
222      * @param bool $endFlag
223      *
224      * @return $this
225      */
226     public function setEndFlag($endFlag)
227     {
228         $this->endFlag = (bool) $endFlag;
229
230         return $this;
231     }
232
233     /**
234      * @return bool
235      */
236     public function hasEndFlag()
237     {
238         return $this->endFlag;
239     }
240
241     /**
242      * @param bool $startJoker
243      *
244      * @return $this
245      */
246     public function setStartJoker($startJoker)
247     {
248         $this->startJoker = $startJoker;
249
250         return $this;
251     }
252
253     /**
254      * @return bool
255      */
256     public function hasStartJoker()
257     {
258         return $this->startJoker;
259     }
260
261     /**
262      * @param bool $endJoker
263      *
264      * @return $this
265      */
266     public function setEndJoker($endJoker)
267     {
268         $this->endJoker = (bool) $endJoker;
269
270         return $this;
271     }
272
273     /**
274      * @return bool
275      */
276     public function hasEndJoker()
277     {
278         return $this->endJoker;
279     }
280
281     /**
282      * @param array $replacement
283      *
284      * @return $this
285      */
286     public function replaceJokers($replacement)
287     {
288         $replace = function ($subject) use ($replacement) {
289             $subject = $subject[0];
290             $replace = 0 === substr_count($subject, '\\') % 2;
291
292             return $replace ? str_replace('.', $replacement, $subject) : $subject;
293         };
294
295         $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
296
297         return $this;
298     }
299
300     /**
301      * @param string $pattern
302      */
303     private function parsePattern($pattern)
304     {
305         if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
306             $pattern = substr($pattern, 1);
307         }
308
309         if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
310             $pattern = substr($pattern, 2);
311         }
312
313         if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
314             $pattern = substr($pattern, 0, -1);
315         }
316
317         if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
318             $pattern = substr($pattern, 0, -2);
319         }
320
321         $this->pattern = $pattern;
322     }
323 }