PageRenderTime 37ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/symfony/finder/Expression/Regex.php

https://bitbucket.org/dannyelps/rea
PHP | 319 lines | 281 code | 15 blank | 23 comment | 6 complexity | 76f28139adf1804e3d0600208c31fc3f MD5 | raw file
Possible License(s): LGPL-2.1, MIT
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Finder\Expression;
  11. /**
  12. * @author Jean-François Simon <contact@jfsimon.fr>
  13. */
  14. class Regex implements ValueInterface
  15. {
  16. const START_FLAG = '^';
  17. const END_FLAG = '$';
  18. const BOUNDARY = '~';
  19. const JOKER = '.*';
  20. const ESCAPING = '\\';
  21. /**
  22. * @var string
  23. */
  24. private $pattern;
  25. /**
  26. * @var string
  27. */
  28. private $options;
  29. /**
  30. * @var bool
  31. */
  32. private $startFlag;
  33. /**
  34. * @var bool
  35. */
  36. private $endFlag;
  37. /**
  38. * @var bool
  39. */
  40. private $startJoker;
  41. /**
  42. * @var bool
  43. */
  44. private $endJoker;
  45. /**
  46. * @param string $expr
  47. *
  48. * @return self
  49. *
  50. * @throws \InvalidArgumentException
  51. */
  52. public static function create($expr)
  53. {
  54. if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
  55. $start = substr($m[1], 0, 1);
  56. $end = substr($m[1], -1);
  57. if (
  58. ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
  59. || ('{' === $start && '}' === $end)
  60. || ('(' === $start && ')' === $end)
  61. ) {
  62. return new self(substr($m[1], 1, -1), $m[2], $end);
  63. }
  64. }
  65. throw new \InvalidArgumentException('Given expression is not a regex.');
  66. }
  67. /**
  68. * @param string $pattern
  69. * @param string $options
  70. * @param string $delimiter
  71. */
  72. public function __construct($pattern, $options = '', $delimiter = null)
  73. {
  74. if (null !== $delimiter) {
  75. // removes delimiter escaping
  76. $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
  77. }
  78. $this->parsePattern($pattern);
  79. $this->options = $options;
  80. }
  81. /**
  82. * @return string
  83. */
  84. public function __toString()
  85. {
  86. return $this->render();
  87. }
  88. /**
  89. * {@inheritdoc}
  90. */
  91. public function render()
  92. {
  93. return self::BOUNDARY
  94. .$this->renderPattern()
  95. .self::BOUNDARY
  96. .$this->options;
  97. }
  98. /**
  99. * {@inheritdoc}
  100. */
  101. public function renderPattern()
  102. {
  103. return ($this->startFlag ? self::START_FLAG : '')
  104. .($this->startJoker ? self::JOKER : '')
  105. .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
  106. .($this->endJoker ? self::JOKER : '')
  107. .($this->endFlag ? self::END_FLAG : '');
  108. }
  109. /**
  110. * {@inheritdoc}
  111. */
  112. public function isCaseSensitive()
  113. {
  114. return !$this->hasOption('i');
  115. }
  116. /**
  117. * {@inheritdoc}
  118. */
  119. public function getType()
  120. {
  121. return Expression::TYPE_REGEX;
  122. }
  123. /**
  124. * {@inheritdoc}
  125. */
  126. public function prepend($expr)
  127. {
  128. $this->pattern = $expr.$this->pattern;
  129. return $this;
  130. }
  131. /**
  132. * {@inheritdoc}
  133. */
  134. public function append($expr)
  135. {
  136. $this->pattern .= $expr;
  137. return $this;
  138. }
  139. /**
  140. * @param string $option
  141. *
  142. * @return bool
  143. */
  144. public function hasOption($option)
  145. {
  146. return false !== strpos($this->options, $option);
  147. }
  148. /**
  149. * @param string $option
  150. *
  151. * @return $this
  152. */
  153. public function addOption($option)
  154. {
  155. if (!$this->hasOption($option)) {
  156. $this->options .= $option;
  157. }
  158. return $this;
  159. }
  160. /**
  161. * @param string $option
  162. *
  163. * @return $this
  164. */
  165. public function removeOption($option)
  166. {
  167. $this->options = str_replace($option, '', $this->options);
  168. return $this;
  169. }
  170. /**
  171. * @param bool $startFlag
  172. *
  173. * @return $this
  174. */
  175. public function setStartFlag($startFlag)
  176. {
  177. $this->startFlag = $startFlag;
  178. return $this;
  179. }
  180. /**
  181. * @return bool
  182. */
  183. public function hasStartFlag()
  184. {
  185. return $this->startFlag;
  186. }
  187. /**
  188. * @param bool $endFlag
  189. *
  190. * @return $this
  191. */
  192. public function setEndFlag($endFlag)
  193. {
  194. $this->endFlag = (bool) $endFlag;
  195. return $this;
  196. }
  197. /**
  198. * @return bool
  199. */
  200. public function hasEndFlag()
  201. {
  202. return $this->endFlag;
  203. }
  204. /**
  205. * @param bool $startJoker
  206. *
  207. * @return $this
  208. */
  209. public function setStartJoker($startJoker)
  210. {
  211. $this->startJoker = $startJoker;
  212. return $this;
  213. }
  214. /**
  215. * @return bool
  216. */
  217. public function hasStartJoker()
  218. {
  219. return $this->startJoker;
  220. }
  221. /**
  222. * @param bool $endJoker
  223. *
  224. * @return $this
  225. */
  226. public function setEndJoker($endJoker)
  227. {
  228. $this->endJoker = (bool) $endJoker;
  229. return $this;
  230. }
  231. /**
  232. * @return bool
  233. */
  234. public function hasEndJoker()
  235. {
  236. return $this->endJoker;
  237. }
  238. /**
  239. * @return $this
  240. */
  241. public function replaceJokers($replacement)
  242. {
  243. $replace = function ($subject) use ($replacement) {
  244. $subject = $subject[0];
  245. $replace = 0 === substr_count($subject, '\\') % 2;
  246. return $replace ? str_replace('.', $replacement, $subject) : $subject;
  247. };
  248. $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
  249. return $this;
  250. }
  251. /**
  252. * @param string $pattern
  253. */
  254. private function parsePattern($pattern)
  255. {
  256. if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
  257. $pattern = substr($pattern, 1);
  258. }
  259. if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
  260. $pattern = substr($pattern, 2);
  261. }
  262. if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
  263. $pattern = substr($pattern, 0, -1);
  264. }
  265. if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
  266. $pattern = substr($pattern, 0, -2);
  267. }
  268. $this->pattern = $pattern;
  269. }
  270. }