├── .gitignore
├── .travis.yml
├── Example.php
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml.dist
├── src
├── Entity
│ └── Expression.php
├── Parser
│ ├── MethodParser.php
│ └── MethodParserInterface.php
├── VerbalExpressions.php
└── VerbalExpressionsScenario.php
└── tests
├── Parser
└── MethodParserTest.php
├── VerbalExpressionsScenarioTest.php
└── VerbalExpressionsTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # General Ignores
2 | /vendor
3 | composer.lock
4 | /phpunit/
5 | # IDEs
6 | .idea/
7 | /nbproject/
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - '5.4'
4 | - '5.5'
5 | - '5.6'
6 | - '7.0'
7 | - '7.1'
8 | - '7.2'
9 | - nightly
10 | matrix:
11 | include:
12 | - php: "5.3"
13 | dist: precise
14 | git:
15 | #there should rarely be a need to clone 50 deep, so this is just reducing build-time
16 | depth: 5
17 | before_script:
18 | # no need to provide coverage more than once and no need for the speedbump otherwise
19 | - if [[ ${TRAVIS_PHP_VERSION:0:3} != "7.1" ]]; then phpenv config-rm xdebug.ini || true ; fi
20 | # no need to test formatting more than once and php_codesniffer does not work with older php
21 | - if [[ ${TRAVIS_PHP_VERSION:0:3} != "5.6" ]]; then composer remove --dev squizlabs/php_codesniffer ; fi
22 | - composer install
23 | script:
24 | # since it's disabled otherwise...
25 | - if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.6" ]]; then composer check-style ; fi
26 | - composer test
27 |
--------------------------------------------------------------------------------
/Example.php:
--------------------------------------------------------------------------------
1 | startOfLine()
13 | ->then("http")
14 | ->maybe("s")
15 | ->then("://")
16 | ->maybe("www.")
17 | ->anythingBut(" ")
18 | ->endOfLine();
19 |
20 | if ($regex->test("http://github.com")) {
21 | echo "valid url". '
';
22 | } else {
23 | echo "invalid url". '
';
24 | }
25 |
26 | if (preg_match($regex, 'http://github.com')) {
27 | echo 'valid url';
28 | } else {
29 | echo 'invalid url';
30 | }
31 |
32 | echo "
". $regex->getRegex() ."
";
33 |
34 | echo $regex->clean(array("modifiers" => "m", "replaceLimit" => 4))
35 | ->find(' ')
36 | ->replace("This is a small test http://somesite.com and some more text.", "-");
37 |
38 |
39 | echo "
";
40 |
41 | // limit
42 | echo $regex ->clean(array("modifiers" => "m"))
43 | ->startOfLine()
44 | ->anyOf("abc")
45 | ->anythingBut(" ")
46 | ->limit(1)
47 | ->withAnyCase()
48 | ->replace("Abracadabra is a nice word", "Ba");
49 |
50 | echo "
";
51 |
52 |
53 |
54 | echo $regex ->clean(array("modifiers" => "gm"))
55 | ->add("\b")
56 | ->word()
57 | ->limit(2, 3)
58 | ->add("\b")
59 | ->replace("test abc ab abcd", "*");
60 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 jehna
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/VerbalExpressions/PHPVerbalExpressions)
2 |
3 | ## PHPVerbalExpressions
4 | - ported from [VerbalExpressions](https://github.com/VerbalExpressions/JSVerbalExpressions)
5 |
6 | VerbalExpressions is a PHP library that helps to construct hard regular expressions.
7 |
8 | ## Installation
9 | The project supports Composer so you have to install [Composer](http://getcomposer.org/doc/00-intro.md#installation-nix) first, before project setup.
10 |
11 | ```sh
12 | $ composer require verbalexpressions/php-verbal-expressions:dev-master
13 | ```
14 |
15 | ## Examples
16 |
17 | ```php
18 | startOfLine()
26 | ->then("http")
27 | ->maybe("s")
28 | ->then("://")
29 | ->maybe("www.")
30 | ->anythingBut(" ")
31 | ->endOfLine();
32 |
33 |
34 | if ($regex->test("http://github.com")) {
35 | echo "valid url". '
';
36 | } else {
37 | echo "invalid url". '
';
38 | }
39 |
40 | if (preg_match($regex, 'http://github.com')) {
41 | echo 'valid url';
42 | } else {
43 | echo 'invalid url';
44 | }
45 |
46 |
47 | echo "". $regex->getRegex() ."
";
48 |
49 | echo $regex->clean(array("modifiers" => "m", "replaceLimit" => 4))
50 | ->find(' ')
51 | ->replace("This is a small test http://somesite.com and some more text.", "-");
52 |
53 | ```
54 |
55 | More examples are available in the following files:
56 |
57 | - [Example.php](Example.php)
58 | - [VerbalExpressionsTest.php](tests/VerbalExpressionsTest.php)
59 |
60 | ### Business readable language expression definition
61 | ```PHP
62 | $definition = 'start, then "http", maybe "s", then "://", maybe "www.", anything but " ", end';
63 | $regex = new VerbalExpressionsScenario($definition);
64 | ```
65 |
66 | ## Methods list
67 |
68 | Name|Description|Usage
69 | :---|:---|:---
70 | add| add values to the expression| add('abc')
71 | startOfLine| mark expression with ^| startOfLine(false)
72 | endOfLine| mark the expression with $|endOfLine()
73 | then|add a string to the expression| add('foo')
74 | find| alias for then| find('foo')
75 | maybe| define a string that might appear once or not| maybe('.com')
76 | anything| accept any string| anything()
77 | anythingBut| accept any string but the specified char| anythingBut(',')
78 | something| accept any non-empty string| something()
79 | somethingBut| anything non-empty except for these chars| somethingBut('a')
80 | replace| shorthand for preg_replace()| replace($source, $val)
81 | lineBreak| match \r \n|lineBreak()
82 | br|shorthand for lineBreak| br()
83 | tab|match tabs \t |tab()
84 | word|match \w+|word()
85 | anyOf| any of the listed chars| anyOf('abc')
86 | any| shorthand for anyOf| any('abc')
87 | range| adds a range to the expression|range(a,z,0,9)
88 | withAnyCase| match case default case sensitive|withAnyCase()
89 | stopAtFirst|toggles the g modifiers|stopAtFirst()
90 | addModifier| add a modifier|addModifier('g')
91 | removeModifier| remove a mofier|removeModifier('g')
92 | searchOneLine| Toggles m modifier|searchOneLine()
93 | multiple|adds the multiple modifier| multiple('*')
94 | _or|wraps the expression in an `or` with the provided value|_or('bar')
95 | limit|adds char limit|limit(1,3)
96 | test| performs a preg_match| test('valid@email.com')
97 |
98 | For all the above method (except `test`) you could use the `VerbalExpressionsScenario`.
99 |
100 | ## Other Implementations
101 | You can see an up to date list of all ports on [VerbalExpressions.github.io](http://VerbalExpressions.github.io).
102 | - [Javascript](https://github.com/jehna/VerbalExpressions)
103 | - [Ruby](https://github.com/VerbalExpressions/RubyVerbalExpressions)
104 | - [C#](https://github.com/VerbalExpressions/CSharpVerbalExpressions)
105 | - [Python](https://github.com/VerbalExpressions/PythonVerbalExpressions)
106 | - [Java](https://github.com/VerbalExpressions/JavaVerbalExpressions)
107 | - [C++](https://github.com/VerbalExpressions/CppVerbalExpressions)
108 |
109 | ## Building the project and running the tests
110 | The project supports Composer so you have to install [Composer](https://getcomposer.org/doc/00-intro.md#installation-nix) first before project setup.
111 |
112 | curl -sS https://getcomposer.org/installer | php
113 | php composer.phar install --dev
114 | ln -s vendor/phpunit/phpunit/phpunit.php phpunit
115 | ./phpunit
116 |
117 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "verbalexpressions/php-verbal-expressions",
3 | "license": "MIT",
4 | "type": "project",
5 | "description": "PHP Regular expressions made easy",
6 | "require": {
7 | "php": ">=5.3"
8 | },
9 | "require-dev": {
10 | "phpunit/phpunit": "* >=4",
11 | "squizlabs/php_codesniffer": "^3.1"
12 | },
13 | "minimum-stability": "stable",
14 | "autoload": {
15 | "psr-4": {
16 | "VerbalExpressions\\PHPVerbalExpressions\\": "src/"
17 | }
18 | },
19 | "autoload-dev": {
20 | "psr-4": {
21 | "VerbalExpressions\\PHPVerbalExpressions\\Tests\\": "tests/"
22 | }
23 | },
24 | "scripts": {
25 | "test": "vendor/bin/phpunit",
26 | "check-style": "phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests",
27 | "fix-style": "phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 | ./tests/
18 |
19 |
20 |
21 |
22 |
23 | ./src
24 |
25 |
26 |
27 |
28 |
29 |
34 |
39 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/Entity/Expression.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class Expression
12 | {
13 | /**
14 | * @var string
15 | */
16 | private $name;
17 |
18 | /**
19 | * @var mixed
20 | */
21 | private $arguments;
22 |
23 | /**
24 | * @param string $name
25 | * @param null $arguments
26 | */
27 | public function __construct($name, $arguments = null)
28 | {
29 | $this->name = $name;
30 | $this->arguments = $arguments;
31 | }
32 |
33 | /**
34 | * Returns the expression's arguments.
35 | *
36 | * @return mixed
37 | */
38 | public function getArguments()
39 | {
40 | return $this->arguments;
41 | }
42 |
43 | /**
44 | * Returns the expression's name.
45 | *
46 | * @return string
47 | */
48 | public function getName()
49 | {
50 | return $this->name;
51 | }
52 | }
--------------------------------------------------------------------------------
/src/Parser/MethodParser.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class MethodParser implements MethodParserInterface
13 | {
14 | const ANYTHING = 'anything';
15 | const ANYTHING_BUT = 'anythingBut';
16 | const SOMETHING = 'something';
17 | const SOMETHING_BUT = 'somethingBut';
18 | const END_OF_LINE = 'endOfLine';
19 | const FIND = 'find';
20 | const MAYBE = 'maybe';
21 | const START_OF_LINE = 'startOfLine';
22 | const THEN = 'then';
23 | const ANY = 'any';
24 | const ANY_OF = 'anyOf';
25 | const BR = 'br';
26 | const LINE_BREAK = 'lineBreak';
27 | const RANGE = 'rangeBridge';
28 | const TAB = 'tab';
29 | const WORD = 'word';
30 | const WITH_ANY_CASE = 'withAnyCase';
31 | const STOP_AT_FIRST = 'stopAtFirst';
32 | const SEARCH_ONE_LINE = 'searchOneLine';
33 | const REPLACE = 'replaceBridge';
34 | const ADD = 'add';
35 | const LIMIT = 'limit';
36 | const MULTIPLE = 'multiple';
37 | const ADD_MODIFIER = 'addModifier';
38 | const REMOVE_MODIFIER = 'removeModifier';
39 | const _OR = '_or';
40 |
41 | /**
42 | * @param string $scenarioString
43 | * @return null
44 | */
45 | public function parse($scenarioString)
46 | {
47 | $definitions = $this->getDefinitions();
48 | foreach ($definitions as $key => $val) {
49 | if (preg_match('/'.$key.'/i', $scenarioString)) {
50 | return $val;
51 | }
52 | }
53 |
54 | return null;
55 | }
56 |
57 | /**
58 | * @return array
59 | */
60 | private function getDefinitions()
61 | {
62 | return array(
63 | 'anythingbut' => self::ANYTHING_BUT,
64 | 'somethingbut' => self::SOMETHING_BUT,
65 | 'something but' => self::SOMETHING_BUT,
66 | 'something' => self::SOMETHING,
67 | 'anything but' => self::ANYTHING_BUT,
68 | 'anything' => self::ANYTHING,
69 | 'end' => self::END_OF_LINE,
70 | 'end of line' => self::END_OF_LINE,
71 | 'endofline' => self::END_OF_LINE,
72 | 'find' => self::FIND,
73 | 'maybe' => self::MAYBE,
74 | 'start' => self::START_OF_LINE,
75 | 'startofline' => self::START_OF_LINE,
76 | 'start of line' => self::START_OF_LINE,
77 | 'then' => self::THEN,
78 | 'anyof' => self::ANY_OF,
79 | 'any of' => self::ANY_OF,
80 | 'linebreak' => self::LINE_BREAK,
81 | 'line break' => self::LINE_BREAK,
82 | 'br' => self::BR,
83 | 'range' => self::RANGE,
84 | 'tab' => self::TAB,
85 | 'word' => self::WORD,
86 | 'withanycase' => self::WITH_ANY_CASE,
87 | 'with any case' => self::WITH_ANY_CASE,
88 | 'any case' => self::WITH_ANY_CASE,
89 | 'any' => self::ANY,
90 | 'stopatfirst' => self::STOP_AT_FIRST,
91 | 'stop at first' => self::STOP_AT_FIRST,
92 | 'stop first' => self::STOP_AT_FIRST,
93 | 'searchoneline' => self::SEARCH_ONE_LINE,
94 | 'search one line' => self::SEARCH_ONE_LINE,
95 | 'replace' => self::REPLACE,
96 | 'add modifier' => self::ADD_MODIFIER,
97 | 'addmodifier' => self::ADD_MODIFIER,
98 | 'add' => self::ADD,
99 | 'remove modifier' => self::REMOVE_MODIFIER,
100 | 'removemodifier' => self::REMOVE_MODIFIER,
101 | 'limit' => self::LIMIT,
102 | 'multiple' => self::MULTIPLE,
103 | 'or' => self::_OR
104 | );
105 | }
106 | }
--------------------------------------------------------------------------------
/src/Parser/MethodParserInterface.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | interface MethodParserInterface
14 | {
15 | /**
16 | * Parses a single declaration feature
17 | * and return the relative VerbalExpression method name.
18 | *
19 | * @param $singleFeatures
20 | *
21 | * @return string|null
22 | */
23 | public function parse($singleFeatures);
24 | }
--------------------------------------------------------------------------------
/src/VerbalExpressions.php:
--------------------------------------------------------------------------------
1 | source .= $this->lastAdded = $value;
46 |
47 | return $this;
48 | }
49 |
50 | /**
51 | * Start of Line
52 | *
53 | * Mark the expression to start at the beginning of the line.
54 | *
55 | * @access public
56 | * @param boolean $enable Enables or disables the line starting. Default value: true
57 | * @return VerbalExpressions
58 | */
59 | public function startOfLine($enable = true)
60 | {
61 | $this->prefixes = $enable ? '^' : '';
62 |
63 | return $this;
64 | }
65 |
66 | /**
67 | * End of line
68 | *
69 | * Mark the expression to end at the last character of the line.
70 | *
71 | * @access public
72 | * @param boolean $enable Enables or disables the line ending. Default value: true
73 | * @return VerbalExpressions
74 | */
75 | public function endOfLine($enable = true)
76 | {
77 | $this->suffixes = $enable ? '$' : '';
78 |
79 | return $this;
80 | }
81 |
82 | /**
83 | * Then
84 | *
85 | * Add a string to the expression
86 | *
87 | * @access public
88 | * @param string $value The string to be looked for
89 | * @return VerbalExpressions
90 | */
91 | public function then($value)
92 | {
93 | return $this->add('(?:' . self::sanitize($value) . ')');
94 | }
95 |
96 | /**
97 | * Find
98 | *
99 | * Alias for then()
100 | *
101 | * @access public
102 | * @param string $value The string to be looked for
103 | * @return VerbalExpressions
104 | */
105 | public function find($value)
106 | {
107 | return $this->then($value);
108 | }
109 |
110 | /**
111 | * Maybe
112 | *
113 | * Add a string to the expression that might appear once (or not).
114 | *
115 | * @access public
116 | * @param string $value The string to be looked for
117 | * @return VerbalExpressions
118 | */
119 | public function maybe($value)
120 | {
121 | return $this->add('(?:' . self::sanitize($value) . ')?');
122 | }
123 |
124 | /**
125 | * Anything
126 | *
127 | * Accept any string
128 | *
129 | * @access public
130 | * @return VerbalExpressions
131 | */
132 | public function anything()
133 | {
134 | return $this->add('(?:.*)');
135 | }
136 |
137 | /**
138 | * AnythingBut
139 | *
140 | * Anything but this chars
141 | *
142 | * @access public
143 | * @param string $value The unaccepted chars
144 | * @return VerbalExpressions
145 | */
146 | public function anythingBut($value)
147 | {
148 | return $this->add('(?:[^' . self::sanitize($value) . ']*)');
149 | }
150 |
151 | /**
152 | * Something
153 | *
154 | * Accept any non-empty string
155 | *
156 | * @access public
157 | * @return VerbalExpressions
158 | */
159 | public function something()
160 | {
161 | return $this->add('(?:.+)');
162 | }
163 |
164 | /**
165 | * Anything but
166 | *
167 | * Anything non-empty except for these chars
168 | *
169 | * @access public
170 | * @param string $value The unaccepted chars
171 | * @return VerbalExpressions
172 | */
173 | public function somethingBut($value)
174 | {
175 | return $this->add('(?:[^' . self::sanitize($value) . ']+)');
176 | }
177 |
178 | /**
179 | * Preg Replace
180 | *
181 | * Shorthand for preg_replace()
182 | *
183 | * @access public
184 | * @param string $source the string that will be affected(subject)
185 | * @param string $value the replacement
186 | * @return VerbalExpressions
187 | */
188 | public function replace($source, $value)
189 | {
190 | // php doesn't have g modifier so we remove it if it's there and we remove limit param
191 | if (strpos($this->modifiers, 'g') !== false) {
192 | $this->modifiers = str_replace('g', '', $this->modifiers);
193 |
194 | return preg_replace($this->getRegex(), $value, $source);
195 | }
196 |
197 | return preg_replace($this->getRegex(), $value, $source, $this->replaceLimit);
198 | }
199 |
200 | /**
201 | * Line break
202 | *
203 | * Match line break
204 | *
205 | * @access public
206 | * @return VerbalExpressions
207 | */
208 | public function lineBreak()
209 | {
210 | return $this->add('(?:\\n|(\\r\\n))');
211 | }
212 |
213 | /**
214 | * Line break
215 | *
216 | * Shorthand for lineBreak
217 | *
218 | * @access public
219 | * @return VerbalExpressions
220 | */
221 | public function br()
222 | {
223 | return $this->lineBreak();
224 | }
225 |
226 | /**
227 | * Tabs
228 | *
229 | * Match tabs.
230 | *
231 | * @access public
232 | * @return VerbalExpressions
233 | */
234 | public function tab()
235 | {
236 | return $this->add('\\t');
237 | }
238 |
239 | /**
240 | * Alpha Numeric
241 | *
242 | * Match any alpha numeric
243 | *
244 | * @access public
245 | * @return VerbalExpressions
246 | */
247 | public function word()
248 | {
249 | return $this->add('\\w+');
250 | }
251 |
252 | /**
253 | * Digit
254 | *
255 | * Match any digit
256 | *
257 | * @access public
258 | * @return VerbalExpressions
259 | */
260 | public function digit()
261 | {
262 | return $this->add('\\d');
263 | }
264 |
265 | /**
266 | * List Chars
267 | *
268 | * Any of the listed chars
269 | *
270 | * @access public
271 | * @param string $value The chars looked for
272 | * @return VerbalExpressions
273 | */
274 | public function anyOf($value)
275 | {
276 | return $this->add('[' . $value . ']');
277 | }
278 |
279 | /**
280 | * Alias
281 | *
282 | * Shorthand for anyOf
283 | *
284 | * @access public
285 | * @param string $value The chars looked for
286 | * @return VerbalExpressions
287 | */
288 | public function any($value)
289 | {
290 | return $this->anyOf($value);
291 | }
292 |
293 | /**
294 | * Add a range
295 | *
296 | * Adds a range to our expression ex: range(a,z) => a-z, range(a,z,0,9) => a-z0-9
297 | *
298 | * @access public
299 | * @return VerbalExpressions
300 | * @throws \InvalidArgumentException
301 | */
302 | public function range()
303 | {
304 | $args = func_get_args();
305 | $arg_num = count($args);
306 |
307 | if ($arg_num%2 != 0) {
308 | throw new \InvalidArgumentException('Number of args must be even', 1);
309 | }
310 |
311 | $value = '[';
312 |
313 | for ($i = 0; $i < $arg_num;) {
314 | $value .= self::sanitize($args[$i++]) . '-' . self::sanitize($args[$i++]);
315 | }
316 |
317 | $value .= ']';
318 |
319 | return $this->add($value);
320 | }
321 |
322 | /**
323 | * Add a modifier
324 | *
325 | * Adds a modifier
326 | *
327 | * @access public
328 | * @param string $modifier
329 | * @return VerbalExpressions
330 | */
331 | public function addModifier($modifier)
332 | {
333 | if (strpos($this->modifiers, $modifier) === false) {
334 | $this->modifiers .= $modifier;
335 | }
336 |
337 | return $this;
338 | }
339 |
340 | /**
341 | * Remove Modifier
342 | *
343 | * Removes a modifier
344 | *
345 | * @access public
346 | * @param string $modifier
347 | * @return VerbalExpressions
348 | */
349 | public function removeModifier($modifier)
350 | {
351 | $this->modifiers = str_replace($modifier, '', $modifier);
352 |
353 | return $this;
354 | }
355 |
356 | /**
357 | * Case Sensitivity
358 | *
359 | * Match case insensitive or sensitive based on $enable value
360 | *
361 | * @access public
362 | * @param boolean $enable Enables or disables case sensitive. Default true
363 | * @return VerbalExpressions
364 | */
365 | public function withAnyCase($enable = true)
366 | {
367 | return $enable ? $this->addModifier('i') : $this->removeModifier('i');
368 | }
369 |
370 | /**
371 | * Stop At First
372 | *
373 | * Toggles g modifier
374 | *
375 | * @access public
376 | * @param boolean $enable Enables or disables g modifier. Default true
377 | * @return VerbalExpressions
378 | */
379 | public function stopAtFirst($enable = true)
380 | {
381 | return $enable ? $this->addModifier('g') : $this->removeModifier('g');
382 | }
383 |
384 | /**
385 | * SearchOneLine
386 | *
387 | * Toggles m modifier
388 | *
389 | * @access public
390 | * @param boolean $enable Enables or disables m modifier. Default true
391 | * @return VerbalExpressions
392 | */
393 | public function searchOneLine($enable = true)
394 | {
395 | return $enable ? $this->addModifier('m') : $this->removeModifier('m');
396 | }
397 |
398 | /**
399 | * Multiple
400 | *
401 | * Adds the multiple modifier at the end of your expression
402 | *
403 | * @access public
404 | * @param string $value Your expression
405 | * @return VerbalExpressions
406 | */
407 | public function multiple($value)
408 | {
409 | $value = self::sanitize($value);
410 |
411 | $last = substr($value, -1);
412 |
413 | if ($last !== '+' && $last !== '*') {
414 | $value .= '+';
415 | }
416 |
417 | return $this->add($value);
418 | }
419 |
420 | /**
421 | * OR
422 | *
423 | * Wraps the current expression in an `or` with $value
424 | * Notice: OR is a reserved keyword in PHP, so this method is prefixed with "_"
425 | *
426 | * @access public
427 | * @param string $value new expression
428 | * @return VerbalExpressions
429 | */
430 | public function _or($value)
431 | {
432 | if (strpos($this->prefixes, '(') === false) {
433 | $this->prefixes .= '(?:';
434 | }
435 |
436 | if (strpos($this->suffixes, ')') === false) {
437 | $this->suffixes .= ')';
438 | }
439 |
440 | $this->add(')|(?:');
441 |
442 | if ($value) {
443 | $this->add($value);
444 | }
445 |
446 | return $this;
447 | }
448 |
449 | /**
450 | * Object to string
451 | *
452 | * PHP Magic method to return a string representation of the object.
453 | *
454 | * @access public
455 | * @return string
456 | */
457 | public function __toString()
458 | {
459 | return $this->getRegex();
460 | }
461 |
462 | /**
463 | * Get the Expression
464 | *
465 | * Creates the final regex.
466 | *
467 | * @access public
468 | * @return string The final regex
469 | */
470 | public function getRegex()
471 | {
472 | return '/' . $this->prefixes . $this->source . $this->suffixes . '/' . $this->modifiers;
473 | }
474 |
475 | /**
476 | * Test
477 | *
478 | * Tests the match of a string to the current regex
479 | *
480 | * @access public
481 | * @param string $value The string to be tested
482 | * @return boolean true if it's a match
483 | */
484 | public function test($value)
485 | {
486 | // php doesn't have g modifier so we remove it if it's there and call preg_match_all()
487 | if (strpos($this->modifiers, 'g') !== false) {
488 | $this->modifiers = str_replace('g', '', $this->modifiers);
489 | $matches = array();//because it's not optional in <5.4
490 | return preg_match_all($this->getRegex(), $value, $matches);
491 | }
492 |
493 | return (bool) preg_match($this->getRegex(), $value);
494 | }
495 |
496 | /**
497 | * Clean
498 | *
499 | * Deletes the current regex for a fresh start
500 | *
501 | * @access public
502 | * @param array $options
503 | * @return VerbalExpressions
504 | */
505 | public function clean(array $options = array())
506 | {
507 | $options = array_merge(
508 | array(
509 | 'prefixes' => '',
510 | 'source' => '',
511 | 'suffixes' => '',
512 | 'modifiers' => 'gm',
513 | 'replaceLimit' => '1'
514 | ),
515 | $options
516 | );
517 | $this->prefixes = $options['prefixes'];
518 | $this->source = $options['source'];
519 | $this->suffixes = $options['suffixes'];
520 | $this->modifiers = $options['modifiers']; // default to global multi line matching
521 | $this->replaceLimit = $options['replaceLimit']; // default to global multi line matching
522 |
523 | return $this;
524 | }
525 |
526 | /**
527 | * Limit
528 | *
529 | * Adds char limit to the last added expression.
530 | * If $max is less then $min the limit will be: At least $min chars {$min,}
531 | * If $max is 0 the limit will be: exactly $min chars {$min}
532 | * If $max bigger then $min the limit will be: at least $min but not more then $max {$min, $max}
533 | *
534 | * @access public
535 | * @param integer $min
536 | * @param integer $max
537 | * @return VerbalExpressions
538 | */
539 | public function limit($min, $max = 0)
540 | {
541 | if ($max == 0) {
542 | $value = '{' . $min . '}';
543 | } elseif ($max < $min) {
544 | $value = '{' . $min . ',}';
545 | } else {
546 | $value = '{' . $min . ',' . $max . '}';
547 | }
548 |
549 | // check if the expression has * or + for the last expression
550 | if (preg_match('/\*|\+/', $this->lastAdded)) {
551 | $l = 1;
552 | $this->source = strrev(str_replace(array('+', '*'), strrev($value), strrev($this->source), $l));
553 |
554 | return $this;
555 | }
556 |
557 | return $this->add($value);
558 | }
559 | }
560 |
--------------------------------------------------------------------------------
/src/VerbalExpressionsScenario.php:
--------------------------------------------------------------------------------
1 |
15 | */
16 | class VerbalExpressionsScenario extends VerbalExpressions
17 | {
18 |
19 | /**
20 | * @var string
21 | */
22 | private $methodDelimiter;
23 |
24 | /**
25 | * @var string
26 | */
27 | private $argumentDelimiter;
28 |
29 | /**
30 | * @var MethodParser
31 | */
32 | private $methodParser;
33 |
34 | /**
35 | * @param string $scenario
36 | * @param string $methodDelimiter
37 | * @param string $argumentDelimiter
38 | * @param null|MethodParserInterface $methodParser
39 | *
40 | * @return VerbalExpressionsScenario
41 | */
42 | public function __construct($scenario, $methodDelimiter = ', ', $argumentDelimiter = '"', $methodParser = null)
43 | {
44 | if (null == $methodParser || !$methodParser instanceof MethodParserInterface) {
45 | $this->methodParser = new MethodParser();
46 | }
47 | $this->methodDelimiter = $methodDelimiter;
48 | $this->argumentDelimiter = $argumentDelimiter;
49 | $parsedScenario = $this->parseScenario($scenario);
50 |
51 | return $this->runScenario($parsedScenario);
52 | }
53 |
54 | /**
55 | * @param string $scenarioString
56 | *
57 | * @return array
58 | */
59 | private function parseScenario($scenarioString)
60 | {
61 | $parsedScenario = array();
62 | $scenarios = explode($this->methodDelimiter, $scenarioString);
63 | foreach ($scenarios as $scenario) {
64 | $arguments = null;
65 | $scenarioElement = explode($this->argumentDelimiter, $scenario);
66 | if (isset($scenarioElement[1])) {
67 | $arguments = $scenarioElement[1];
68 | }
69 | $parsedScenario[] = new Expression($this->methodParser->parse($scenarioElement[0]), $arguments);
70 | }
71 |
72 | return $parsedScenario;
73 | }
74 |
75 | /**
76 | * @param array $parsedScenario
77 | *
78 | * @return VerbalExpressions
79 | */
80 | private function runScenario($parsedScenario)
81 | {
82 | foreach ($parsedScenario as $expression) {
83 | call_user_func_array(array($this, $expression->getName()), array($expression->getArguments()));
84 | }
85 |
86 | return $this;
87 | }
88 |
89 | /**
90 | * @param null $range
91 | *
92 | * @return VerbalExpressions
93 | * @throws \InvalidArgumentException
94 | */
95 | public function rangeBridge($range = null)
96 | {
97 | $range = explode(",", $range);
98 | call_user_func_array(array($this, 'range'), $range);
99 | }
100 |
101 | /**
102 | * @param array $arguments
103 | */
104 | public function replaceBridge($arguments)
105 | {
106 | call_user_func(array($this, 'replace'), $arguments[0], $arguments[1]);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/tests/Parser/MethodParserTest.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | class MethodParserTest extends TestCase
14 | {
15 | private $methodParser;
16 |
17 | public function setUp()
18 | {
19 | $this->methodParser = new MethodParser();
20 | }
21 |
22 | public function testParseWithEmptyText()
23 | {
24 | $this->assertNull($this->methodParser->parse(''));
25 | }
26 |
27 | /**
28 | * @dataProvider methodsList
29 | */
30 | public function testParse($text, $expected)
31 | {
32 | $this->assertEquals($expected, $this->methodParser->parse($text));
33 | }
34 |
35 | public function methodsList()
36 | {
37 | return array(
38 | array('anythingBut', MethodParser::ANYTHING_BUT),
39 | array('anything But', MethodParser::ANYTHING_BUT),
40 | array('somethingBut', MethodParser::SOMETHING_BUT),
41 | array('something but', MethodParser::SOMETHING_BUT),
42 | array('something', MethodParser::SOMETHING),
43 | array('anything but', MethodParser::ANYTHING_BUT),
44 | array('anything', MethodParser::ANYTHING),
45 | array('end', MethodParser::END_OF_LINE),
46 | array('find', MethodParser::FIND),
47 | array('maybe', MethodParser::MAYBE),
48 | array('start', MethodParser::START_OF_LINE),
49 | array('then', MethodParser::THEN),
50 | array('any', MethodParser::ANY),
51 | array('anyof', MethodParser::ANY_OF),
52 | array('any of', MethodParser::ANY_OF),
53 | array('br', MethodParser::BR),
54 | array('linebreak', MethodParser::LINE_BREAK),
55 | array('line break', MethodParser::LINE_BREAK),
56 | array('range', MethodParser::RANGE),
57 | array('tab', MethodParser::TAB),
58 | array('word', MethodParser::WORD),
59 | array('withanycase', MethodParser::WITH_ANY_CASE),
60 | array('with any case', MethodParser::WITH_ANY_CASE),
61 | array('any case', MethodParser::WITH_ANY_CASE),
62 | array('stopatfirst', MethodParser::STOP_AT_FIRST),
63 | array('stop at first', MethodParser::STOP_AT_FIRST),
64 | array('stop first', MethodParser::STOP_AT_FIRST),
65 | array('searchoneline', MethodParser::SEARCH_ONE_LINE),
66 | array('search one line', MethodParser::SEARCH_ONE_LINE),
67 | array('add modifier', MethodParser::ADD_MODIFIER),
68 | array('remove modifier', MethodParser::REMOVE_MODIFIER),
69 | array('replace', MethodParser::REPLACE),
70 | array('add', MethodParser::ADD),
71 | array('limit', MethodParser::LIMIT),
72 | array('multiple', MethodParser::MULTIPLE),
73 | array('or', MethodParser::_OR)
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/tests/VerbalExpressionsScenarioTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($expectation, (string)$reg, sprintf('The expected result "%s" is wrongly generated by the expression "%s"', $expectation, $expression));
16 | }
17 |
18 | public function expressionProvider()
19 | {
20 | return array(
21 | array('start, then "http", range "a,z,1,2", end', '/(?:http)[a-z1-2]/m'),
22 | array('start, anythingBut "http", maybe "zed", end', '/(?:[^http]*)(?:zed)?/m'),
23 | array('start, any "foo", br, linebreak, tab, end', '/[foo](?:\n|(\r\n))(?:\n|(\r\n))\t/m'),
24 | array('start, any "http", br, end', '/[http](?:\n|(\r\n))/m'),
25 | array('start, anyOf "12", then "foo", end', '/[12](?:foo)/m'),
26 | array('start, anything, word, end', '/(?:.*)\w+/m'),
27 | array('start, then "foo", withAnyCase, end', '/(?:foo)/'),
28 | array('start, then "foo", stopAtFirst, searchOneLINE, end', '/(?:foo)/'),
29 | array('start, then "foo", or "bar", end', '/(?:(?:foo))|(?:bar/m'),
30 | array('start, word, limit "3", end', '/\w{3}/m'),
31 | array('start, find "foo", replace "foo,bar", end', '/(?:foo)/m'),
32 | array('start, then "abc", multiple "2", end', '/(?:abc)2+/m'),
33 | array('start, then "abc", add "something", end', '/(?:abc)something/m'),
34 | array('something', '/(?:.+)/m'),
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/VerbalExpressionsTest.php:
--------------------------------------------------------------------------------
1 | buildUrlPattern($regex);
18 |
19 | $this->assertTrue($regex->test($url));
20 |
21 |
22 | $regex = new VerbalExpressions();
23 | $this->buildUrlPatternAliased($regex);
24 |
25 | $this->assertTrue($regex->test($url));
26 | }
27 |
28 | public static function provideValidUrls()
29 | {
30 | return array(
31 | array('http://github.com'),
32 | array('http://www.github.com'),
33 | array('https://github.com'),
34 | array('https://www.github.com'),
35 | array('https://github.com/blog'),
36 | array('https://foobar.github.com')
37 | );
38 | }
39 |
40 | /**
41 | * @dataProvider provideInvalidUrls
42 | * @group functional
43 | */
44 | public function testShouldFailWithInvalidUrls($url)
45 | {
46 | $regex = new VerbalExpressions();
47 | $this->buildUrlPattern($regex);
48 |
49 | $this->assertFalse($regex->test($url));
50 | }
51 |
52 | public static function provideInvalidUrls()
53 | {
54 | return array(
55 | array(' http://github.com'),
56 | array('foo'),
57 | array('htps://github.com'),
58 | array('http:/github.com'),
59 | array('https://github.com /blog'),
60 | );
61 | }
62 |
63 | protected function buildUrlPattern(VerbalExpressions $regex)
64 | {
65 | return $regex->startOfLine()
66 | ->then("http")
67 | ->maybe("s")
68 | ->then("://")
69 | ->maybe("www.")
70 | ->anythingBut(" ")
71 | ->endOfLine();
72 | }
73 |
74 | protected function buildUrlPatternAliased(VerbalExpressions $regex)
75 | {
76 | return $regex->startOfLine()
77 | ->find("http")
78 | ->maybe("s")
79 | ->find("://")
80 | ->maybe("www.")
81 | ->anythingBut(" ")
82 | ->endOfLine();
83 | }
84 |
85 |
86 | public function testTest()
87 | {
88 | $regex = new VerbalExpressions();
89 | $regex->find('regex');
90 |
91 | $this->assertTrue($regex->test('testing regex string'));
92 | $this->assertFalse($regex->test('testing string'));
93 |
94 | $regex->stopAtFirst();
95 |
96 | $this->assertEquals(1, $regex->test('testing regex string'));
97 | $this->assertFalse($regex->test('testing string'));
98 | }
99 |
100 | /**
101 | * @depends testTest
102 | */
103 | public function testThenAfterStartOfLine()
104 | {
105 | $regex = new VerbalExpressions();
106 | $regex->startOfLine()
107 | ->then('a')
108 | ->endOfLine();
109 |
110 | $this->assertTrue($regex->test('a'));
111 | $this->assertFalse($regex->test('ba'));
112 | }
113 |
114 | public function testThenSomewhere()
115 | {
116 | $regex = new VerbalExpressions();
117 | $regex->startOfLine(false)
118 | ->then('a')
119 | ->endOfLine(false);
120 |
121 | $this->assertTrue($regex->test('a'));
122 | $this->assertTrue($regex->test('ba'));
123 | }
124 |
125 | /**
126 | * @dataProvider provideAnything
127 | */
128 | public function testAnything($needle)
129 | {
130 | $regex = new VerbalExpressions();
131 | $regex->startOfLine()
132 | ->anything()
133 | ->endOfLine();
134 |
135 | $this->assertTrue($regex->test($needle));
136 | }
137 |
138 | public static function provideAnything()
139 | {
140 | return array(
141 | array('a'),
142 | array('foo'),
143 | array('bar'),
144 | array('!'),
145 | array(' dfs fdslf sdlfk '),
146 | array('t ( - _ - t )'),
147 | );
148 | }
149 |
150 | public function testAnythingBut()
151 | {
152 | $regex = new VerbalExpressions();
153 | $regex->startOfLine()
154 | ->anythingBut('a')
155 | ->endOfLine();
156 |
157 | $this->assertTrue($regex->test('bcdefg h I A'));
158 | $this->assertFalse($regex->test('a'));
159 | $this->assertFalse($regex->test('fooa'));
160 | }
161 |
162 | public function testAnythingButQuote()
163 | {
164 | $regex = new VerbalExpressions();
165 | $regex->startOfLine()
166 | ->anythingBut('[')
167 | ->endOfLine();
168 |
169 | $this->assertTrue($regex->test('abcd'));
170 | $this->assertTrue($regex->test('ab\cd'));
171 | $this->assertFalse($regex->test('ab[cd'));
172 | $this->assertFalse($regex->test('['));
173 | $this->assertFalse($regex->test('['));
174 | $this->assertFalse($regex->test('\['));
175 | }
176 |
177 | public function testSomething()
178 | {
179 | $regex = new VerbalExpressions();
180 | $regex->startOfLine()
181 | ->something()
182 | ->endOfLine();
183 |
184 | $this->assertTrue($regex->test('foobar'));
185 | $this->assertTrue($regex->test('foobar!'));
186 | $this->assertTrue($regex->test('foo bar'));
187 | $this->assertFalse($regex->test(''));
188 | }
189 |
190 | public function testSomethingBut()
191 | {
192 | $regex = new VerbalExpressions();
193 | $regex->startOfLine()
194 | ->somethingBut('a')
195 | ->endOfLine();
196 |
197 | $this->assertTrue($regex->test('foobr'));
198 | $this->assertTrue($regex->test('foobr!'));
199 | $this->assertTrue($regex->test('foo br'));
200 | $this->assertFalse($regex->test('a'));
201 | $this->assertFalse($regex->test('bar'));
202 | $this->assertFalse($regex->test('foo bar'));
203 | $this->assertFalse($regex->test(''));
204 | }
205 |
206 | public function testBr()
207 | {
208 | $regex = new VerbalExpressions();
209 | $regex->startOfLine()
210 | ->something()
211 | ->br()
212 | ->something()
213 | ->endOfLine();
214 |
215 | $this->assertTrue($regex->test("foo\nbar"));
216 | $this->assertFalse($regex->test("foo bar"));
217 | }
218 |
219 | public function testLineBreak()
220 | {
221 | $regex = new VerbalExpressions();
222 | $regex->startOfLine()
223 | ->something()
224 | ->lineBreak()
225 | ->something()
226 | ->endOfLine();
227 |
228 | $this->assertTrue($regex->test("foo\nbar"));
229 | $this->assertFalse($regex->test("foo bar"));
230 | }
231 |
232 | public function testTab()
233 | {
234 | $regex = new VerbalExpressions();
235 | $regex->startOfLine()
236 | ->something()
237 | ->tab()
238 | ->something()
239 | ->endOfLine();
240 |
241 | $this->assertTrue($regex->test("foo\tbar"));
242 | $this->assertFalse($regex->test("foo bar"));
243 | }
244 |
245 | public function testWord()
246 | {
247 | $regex = new VerbalExpressions();
248 | $regex->startOfLine()
249 | ->word()
250 | ->endOfLine();
251 |
252 | $this->assertTrue($regex->test('abcdefghijklmnopqrstuvwxyz0123456789_'));
253 | $this->assertTrue($regex->test('ABCDEFGHIJKLMNOPQRSTUVWXYZ'));
254 | $this->assertTrue($regex->test('a_c'));
255 | $this->assertFalse($regex->test('a-b'));
256 | $this->assertFalse($regex->test('a b'));
257 | $this->assertFalse($regex->test('a!b'));
258 | }
259 |
260 |
261 | public function testDigit()
262 | {
263 | $regex = new VerbalExpressions();
264 | $regex->digit();
265 |
266 | $this->assertTrue($regex->test('0123456789'));
267 |
268 | foreach (str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ_-@,./%*') as $char) {
269 | $this->assertFalse($regex->test($char), 'Should not match digit ('.$char.')');
270 | }
271 | }
272 |
273 | public function testAny()
274 | {
275 | $regex = new VerbalExpressions();
276 | $regex->startOfLine()
277 | ->any('a1M')
278 | ->endOfLine();
279 |
280 | $this->assertTrue($regex->test('a'));
281 | $this->assertTrue($regex->test('1'));
282 | $this->assertTrue($regex->test('M'));
283 | $this->assertFalse($regex->test('b'));
284 | $this->assertFalse($regex->test(''));
285 | $this->assertFalse($regex->test(' '));
286 | }
287 |
288 | public function testAnyOf()
289 | {
290 | $regex = new VerbalExpressions();
291 | $regex->startOfLine()
292 | ->anyOf('a1M')
293 | ->endOfLine();
294 |
295 | $this->assertTrue($regex->test('a'));
296 | $this->assertTrue($regex->test('1'));
297 | $this->assertTrue($regex->test('M'));
298 | $this->assertFalse($regex->test('b'));
299 | $this->assertFalse($regex->test(''));
300 | $this->assertFalse($regex->test(' '));
301 | }
302 |
303 |
304 | public function testGetRegex()
305 | {
306 | $regex = new VerbalExpressions();
307 | $regex->startOfLine()
308 | ->range(0, 9, 'a', 'z', 'A', 'Z')
309 | ->multiple('');
310 |
311 | $this->assertEquals('/^[0-9a-zA-Z]+/m', $regex->getRegex());
312 | $this->assertEquals('/^[0-9a-zA-Z]+/m', $regex->__toString());
313 | $this->assertEquals('/^[0-9a-zA-Z]+/m', (string)$regex);
314 | $this->assertEquals('/^[0-9a-zA-Z]+/m', $regex . '');
315 | }
316 |
317 | /**
318 | * @depends testGetRegex
319 | */
320 | public function testGetRegexMultiple()
321 | {
322 | $regex = new VerbalExpressions();
323 | $regex->startOfLine()
324 | ->multiple('regex');
325 |
326 | $this->assertEquals('/^regex+/m', $regex->getRegex());
327 | }
328 |
329 | /**
330 | * @expectedException InvalidArgumentException
331 | */
332 | public function testRangeThrowsException()
333 | {
334 | $regex = new VerbalExpressions();
335 | $regex->range(1, 2, 3);
336 | }
337 |
338 | /**
339 | * @depends testGetRegex
340 | */
341 | public function testRangeLowercase()
342 | {
343 | $lowercaseAlpha = new VerbalExpressions();
344 | $lowercaseAlpha->range('a', 'z')
345 | ->multiple('');
346 |
347 | $lowercaseAlpha_all = new VerbalExpressions();
348 | $lowercaseAlpha_all->startOfLine()
349 | ->range('a', 'z')
350 | ->multiple('')
351 | ->endOfLine();
352 |
353 | $this->assertEquals('/[a-z]+/m', $lowercaseAlpha->getRegex());
354 | $this->assertEquals('/^[a-z]+$/m', $lowercaseAlpha_all->getRegex());
355 |
356 | $this->assertTrue($lowercaseAlpha->test('a'));
357 | $this->assertFalse($lowercaseAlpha->test('A'));
358 | $this->assertTrue($lowercaseAlpha->test('alphabet'));
359 | $this->assertTrue($lowercaseAlpha->test('Alphabet'));
360 | $this->assertFalse($lowercaseAlpha_all->test('Alphabet'));
361 | }
362 |
363 | /**
364 | * @depends testGetRegex
365 | */
366 | public function testRangeUppercase()
367 | {
368 | $uppercaseAlpha = new VerbalExpressions();
369 | $uppercaseAlpha->range('A', 'Z')
370 | ->multiple('');
371 |
372 | $uppercaseAlpha_all = new VerbalExpressions();
373 | $uppercaseAlpha_all->startOfLine()
374 | ->range('A', 'Z')
375 | ->multiple('')
376 | ->endOfLine();
377 |
378 | $this->assertEquals('/[A-Z]+/m', $uppercaseAlpha->getRegex());
379 | $this->assertEquals('/^[A-Z]+$/m', $uppercaseAlpha_all->getRegex());
380 |
381 | $this->assertTrue($uppercaseAlpha->test('A'));
382 | $this->assertFalse($uppercaseAlpha->test('a'));
383 | $this->assertFalse($uppercaseAlpha->test('alphabet'));
384 | $this->assertTrue($uppercaseAlpha->test('Alphabet'));
385 | $this->assertTrue($uppercaseAlpha->test('ALPHABET'));
386 | $this->assertFalse($uppercaseAlpha_all->test('Alphabet'));
387 | $this->assertTrue($uppercaseAlpha_all->test('ALPHABET'));
388 | }
389 |
390 | /**
391 | * @depends testGetRegex
392 | */
393 | public function testRangeNumerical()
394 | {
395 | $zeroToNine = new VerbalExpressions();
396 | $zeroToNine->range(0, 9)
397 | ->multiple('');
398 |
399 | $zeroToNine_all = new VerbalExpressions();
400 | $zeroToNine_all->startOfLine()
401 | ->range(0, 9)
402 | ->multiple('')
403 | ->endOfLine();
404 |
405 | $this->assertEquals('/[0-9]+/m', $zeroToNine->getRegex());
406 | $this->assertEquals('/^[0-9]+$/m', $zeroToNine_all->getRegex());
407 |
408 | $this->assertFalse($zeroToNine->test('alphabet'));
409 | $this->assertTrue($zeroToNine->test(0));
410 | $this->assertTrue($zeroToNine->test('0'));
411 | $this->assertTrue($zeroToNine->test(123));
412 | $this->assertTrue($zeroToNine->test('123'));
413 | $this->assertTrue($zeroToNine->test(1.23));
414 | $this->assertTrue($zeroToNine->test('1.23'));
415 | $this->assertFalse($zeroToNine_all->test(1.23));
416 | $this->assertFalse($zeroToNine_all->test('1.23'));
417 | $this->assertTrue($zeroToNine->test('£123'));
418 | $this->assertFalse($zeroToNine_all->test('£123'));
419 | }
420 |
421 | /**
422 | * @depends testGetRegex
423 | */
424 | public function testRangeHexadecimal()
425 | {
426 | $hexadecimal = new VerbalExpressions();
427 | $hexadecimal->startOfLine()
428 | ->range(0, 9, 'a', 'f')
429 | ->multiple('')
430 | ->endOfLine();
431 |
432 | $this->assertEquals('/^[0-9a-f]+$/m', $hexadecimal->getRegex());
433 |
434 | $this->assertFalse($hexadecimal->test('alphabet'));
435 | $this->assertTrue($hexadecimal->test('deadbeef'));
436 | $this->assertTrue($hexadecimal->test(md5('')));
437 | $this->assertTrue($hexadecimal->test(sha1('')));
438 | }
439 |
440 | /**
441 | * @depends testRangeHexadecimal
442 | */
443 | public function testRangeMd5()
444 | {
445 | $md5 = new VerbalExpressions();
446 | $md5->startOfLine()
447 | ->range(0, 9, 'a', 'f')
448 | ->limit(32)
449 | ->endOfLine();
450 |
451 | $this->assertEquals('/^[0-9a-f]{32}$/m', $md5->getRegex());
452 |
453 | $this->assertFalse($md5->test('alphabet'));
454 | $this->assertFalse($md5->test('deadbeef'));
455 | $this->assertTrue($md5->test(md5('')));
456 | $this->assertFalse($md5->test(sha1('')));
457 | }
458 |
459 | /*
460 | * @depends testRangeHexadecimal
461 | */
462 | public function testRangeSha1()
463 | {
464 | $sha1 = new VerbalExpressions();
465 | $sha1->startOfLine()
466 | ->range(0, 9, 'a', 'f')
467 | ->limit(40)
468 | ->endOfLine();
469 |
470 | $this->assertEquals('/^[0-9a-f]{40}$/m', $sha1->getRegex());
471 |
472 | $this->assertFalse($sha1->test('alphabet'));
473 | $this->assertFalse($sha1->test('deadbeef'));
474 | $this->assertFalse($sha1->test(md5('')));
475 | $this->assertTrue($sha1->test(sha1('')));
476 | }
477 |
478 | /**
479 | * @depends testGetRegex
480 | */
481 | public function testRemoveModifier()
482 | {
483 | $regex = new VerbalExpressions();
484 | $regex->range('a', 'z');
485 |
486 | $this->assertEquals('/[a-z]/m', $regex->getRegex());
487 |
488 | $regex->removeModifier('m');
489 |
490 | $this->assertEquals('/[a-z]/', $regex->getRegex());
491 | }
492 |
493 | /**
494 | * @depends testRemoveModifier
495 | */
496 | public function testWithAnyCase()
497 | {
498 | $regex = new VerbalExpressions();
499 | $regex->range('a', 'z')
500 | ->searchOneLine(false)
501 | ->withAnyCase();
502 |
503 | $this->assertEquals('/[a-z]/i', $regex->getRegex());
504 |
505 | $regex->withAnyCase(false);
506 |
507 | $this->assertEquals('/[a-z]/', $regex->getRegex());
508 | }
509 |
510 | /**
511 | * @depends testGetRegex
512 | */
513 | public function testOr()
514 | {
515 | $regex = new VerbalExpressions();
516 | $regex->find('foo')
517 | ->_or('bar');
518 |
519 | $this->assertTrue($regex->test('foo'));
520 | $this->assertTrue($regex->test('bar'));
521 | $this->assertFalse($regex->test('baz'));
522 | $this->assertTrue($regex->test('food'));
523 |
524 | $this->assertEquals('/(?:(?:foo))|(?:bar)/m', $regex->getRegex());
525 | }
526 |
527 | /**
528 | * @depends testGetRegex
529 | * @todo fix VerbalExpressions::clean() so it matches initial state
530 | */
531 | public function testClean()
532 | {
533 | $regex = new VerbalExpressions();
534 | $regex->removeModifier('m')
535 | ->stopAtFirst()
536 | ->searchOneLine();
537 |
538 | $regex_at_start = $regex->getRegex();
539 | $regex->find('something')
540 | ->add('else')
541 | ->_or('another');
542 |
543 | $this->assertNotEquals($regex_at_start, $regex->getRegex());
544 |
545 | $regex->clean();
546 |
547 | $this->assertEquals($regex_at_start, $regex->getRegex());
548 | }
549 |
550 | /**
551 | * @depends testGetRegex
552 | */
553 | public function testLimit()
554 | {
555 | $regex = new VerbalExpressions();
556 |
557 | $regex->add('a')
558 | ->limit(1);
559 | $this->assertEquals('/a{1}/m', $regex->getRegex());
560 |
561 | $regex->add('b')
562 | ->limit(2, 1);
563 | $this->assertEquals('/a{1}b{2,}/m', $regex->getRegex());
564 |
565 | $regex->add('c')
566 | ->limit(3, 4);
567 | $this->assertEquals('/a{1}b{2,}c{3,4}/m', $regex->getRegex());
568 |
569 | $regex->multiple('d');
570 | $this->assertEquals('/a{1}b{2,}c{3,4}d+/m', $regex->getRegex());
571 |
572 | $regex->limit(5, 6);
573 | $this->assertEquals('/a{1}b{2,}c{3,4}d{5,6}/m', $regex->getRegex());
574 | }
575 |
576 | /**
577 | * @depends testGetRegex
578 | */
579 | public function testReplace()
580 | {
581 | $regex = new VerbalExpressions();
582 | $regex->add('foo');
583 |
584 | $this->assertEquals('/foo/m', $regex->getRegex());
585 | $this->assertEquals('bazbarfoo', $regex->replace('foobarfoo', 'baz'));
586 |
587 | $regex->stopAtFirst();
588 |
589 | $this->assertEquals('/foo/mg', $regex->getRegex());
590 | $this->assertEquals('bazbarbaz', $regex->replace('foobarfoo', 'baz'));
591 | }
592 | }
593 |
--------------------------------------------------------------------------------