├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── composer.json └── src └── RegRev ├── Configuration.php ├── Debug.php ├── Exception └── RegExpNotValidException.php ├── ExpressionContainer.php ├── Metacharacter ├── CharType │ ├── CharListInterface.php │ ├── CharType.php │ ├── Generic.php │ └── Unknown.php ├── CharacterHandler.php ├── GroupType │ └── Subpattern.php ├── Quantifier │ ├── NTimes.php │ ├── OneOrMore.php │ ├── ZeroOrMore.php │ └── ZeroOrOne.php └── Range │ ├── Alternation.php │ └── Range.php └── RegRev.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | 0.4.0 / 2015-06-16 4 | ================= 5 | * Add alternation 6 | * Add not in range feature 7 | * Fix minor bugs 8 | 9 | 0.3.0 / 2015-05-06 10 | ================= 11 | * Add debug feature 12 | 13 | 0.2.0 / 2015-05-05 14 | ================= 15 | * Add configuration feature 16 | 17 | 0.1.1 / 2015-05-01 18 | ================== 19 | * Fix bug with patterns like ([)(]) 20 | 21 | 0.1.0 / 2015-04-29 22 | ================== 23 | * Add range support 24 | * Add quantifier support 25 | * Add subpattern support 26 | * Refactor classes 27 | * Fix minor bugs 28 | 29 | 0.0.2 / 2015-04-13 30 | ================== 31 | * Add more character types support 32 | * Add non blank space support 33 | * Add non alphanumeric support 34 | 35 | 0.0.1 / 2015-04-10 36 | ================== 37 | * Initial release 38 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | We accept contributions via Pull Requests on [Github](https://github.com/niklongstone/regex-reverse). 6 | 7 | 8 | ## Pull Requests 9 | 10 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). 11 | 12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 13 | 14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 15 | 16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 17 | 18 | - **Create feature branches** - Don't ask us to pull from your master branch. 19 | 20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 21 | 22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting. 23 | 24 | 25 | ## Running Tests 26 | 27 | ``` bash 28 | $ phpunit 29 | ``` 30 | 31 | 32 | **Happy coding**! 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Nicola Pietroluongo 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all 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, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Regex reverse 2 | 3 | [![Latest Version](https://img.shields.io/github/release/niklongstone/regex-reverse.svg?style=flat-square)](https://github.com/niklongstone/regex-reverse/releases) 4 | [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) 5 | [![Build Status](https://img.shields.io/travis/niklongstone/regex-reverse/master.svg?style=flat-square)](https://travis-ci.org/niklongstone/regex-reverse) 6 | [![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/niklongstone/regex-reverse.svg?style=flat-square)](https://scrutinizer-ci.com/g/niklongstone/regex-reverse/code-structure) 7 | [![Quality Score](https://img.shields.io/scrutinizer/g/niklongstone/regex-reverse.svg?style=flat-square)](https://scrutinizer-ci.com/g/niklongstone/regex-reverse) 8 | 9 | 10 | Regular expression reverter, generates a string from the given regular expression. 11 | 12 | ## Install 13 | 14 | Via [Composer](https://getcomposer.org/download/) 15 | 16 | ``` bash 17 | $ composer require niklongstone/regex-reverse:'^0.4.0' 18 | ``` 19 | 20 | ## Usage 21 | 22 | ``` php 23 | .*?<\/TAG>` |`ZPXApG` | TAG | 74 | | `004[0-9] \d{7,10}` | 0044 75132145 | europe phone | 75 | |`SE[1-9]{1}\d{1}\s[A-Z]{2}\d{2}`| SE27 GU35 | london SE post code | 76 | |`SE[1-9]{1}\d{1}\s[A-Z]{2}\d{2}`| SE27 GU35 | london SE post code | 77 | | `organi[sz]e` | organise or organize | US or UK spelling | 78 | 79 | 80 | ## Other features 81 | - debug: `RegRev::debug()` will return an array of messages 82 | 83 | ## Contributing 84 | 85 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 86 | 87 | ## Credits 88 | 89 | - [Nicola Pietroluongo](https://github.com/niklongstone) 90 | 91 | ## License 92 | 93 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 94 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "niklongstone/regex-reverse", 3 | "description": "Regular Expression reverter, generates a string from a provided regular expression", 4 | "keywords": [ 5 | "regular expression", "generation", "test", "data", "regex", "preg", "PCRE" 6 | ], 7 | "homepage": "https://github.com/niklongstone/reverse-regex", 8 | "type": "library", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "Nicola Pietroluongo", 13 | "email": "nik.longstone@gmail.com", 14 | "homepage": "http://www.nicolapietroluongo.com" 15 | } 16 | ], 17 | "require": { 18 | "php" : ">=5.3.0" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit" : "4.*" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "RegRev\\": "src/RegRev/" 26 | } 27 | }, 28 | "autoload-dev": { 29 | "psr-4": { 30 | "RegRev\\Test\\": "tests/RegRev/" 31 | } 32 | }, 33 | "extra": { 34 | "branch-alias": { 35 | "dev-master": "1.0-dev" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/RegRev/Configuration.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev; 12 | 13 | /** 14 | * Class RevReg 15 | */ 16 | class Configuration 17 | { 18 | private $config; 19 | 20 | /** 21 | * Constructor. 22 | */ 23 | public function __construct() 24 | { 25 | $this->config = array( 26 | array( 27 | 'name' => 'Digit', 28 | 'type' => 'CharType\\CharType', 29 | 'chars' => '0123456789', 30 | 'pattern' => array('\d') 31 | ), 32 | array( 33 | 'name' => 'Non Digit', 34 | 'type' => 'CharType\\CharType', 35 | 'chars' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 36 | 'pattern' => array('\D') 37 | ), 38 | array( 39 | 'name' => 'Alphanumeric', 40 | 'type' => 'CharType\\CharType', 41 | 'chars' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY', 42 | 'pattern' => array('\w','\S','.') 43 | ), 44 | array( 45 | 'name' => 'Non Alphanumeric', 46 | 'type' => 'CharType\\CharType', 47 | 'chars' => './\\()"\':,.;<>~!@#$%^&*|+=[]{}`~?-', 48 | 'pattern' => array('\W') 49 | ), 50 | array( 51 | 'name' => 'Subpattern', 52 | 'type' => 'GroupType\Subpattern', 53 | 'pattern' => array('/^(\(((?>[^()]+)|(?-2))*\))/') 54 | ), 55 | array( 56 | 'name' => 'Range', 57 | 'type' => 'Range\Range', 58 | 'chars' => '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY./\\()"\':,.;<>~!@#$%^&*|+=[]{}`~?-', 59 | 'pattern' => array('/^\[[^\]]*\]/') 60 | ), 61 | array( 62 | 'type' => 'Quantifier\ZeroOrMore', 63 | 'pattern' => array('*') 64 | ), 65 | array( 66 | 'type' => 'Quantifier\OneOrMore', 67 | 'pattern' => array('+') 68 | ), 69 | array( 70 | 'type' => 'Quantifier\ZeroOrOne', 71 | 'pattern' => array('?') 72 | ), 73 | array( 74 | 'type' => 'Quantifier\NTimes', 75 | 'pattern' => array('/^\{(\d*),?(\d*)?\}/') 76 | ), 77 | array( 78 | 'name' => 'Alternation', 79 | 'type' => 'Range\Alternation', 80 | 'pattern' => array('|') 81 | ), 82 | array( 83 | 'name' => 'Blank space', 84 | 'type' => 'CharType\Generic', 85 | 'pattern' => array('\h','\s'), 86 | 'returnValue' => ' ' 87 | ), 88 | /** 89 | * Ignored 90 | */ 91 | array( 92 | 'name' => 'Start', 93 | 'type' => 'CharType\Generic', 94 | 'pattern' => array('^'), 95 | 'returnValue' => '' 96 | ), 97 | array( 98 | 'name' => 'End', 99 | 'type' => 'CharType\Generic', 100 | 'pattern' => array('$'), 101 | 'returnValue' => '' 102 | ), 103 | /** 104 | * Escaped meta-character 105 | */ 106 | array( 107 | 'name' => 'Escaped dot', 108 | 'type' => 'CharType\Generic', 109 | 'pattern' => array('\.'), 110 | 'returnValue' => '.' 111 | ), 112 | array( 113 | 'name' => 'Left Round bracket (', 114 | 'type' => 'CharType\Generic', 115 | 'pattern' => array('\('), 116 | 'returnValue' => '(' 117 | ), 118 | array( 119 | 'name' => 'Right Round bracket )', 120 | 'type' => 'CharType\Generic', 121 | 'pattern' => array('\)'), 122 | 'returnValue' => ')' 123 | ), 124 | array( 125 | 'name' => 'Escaped Slash', 126 | 'type' => 'CharType\Generic', 127 | 'pattern' => array('\/'), 128 | 'returnValue' => '/' 129 | ), 130 | array( 131 | 'name' => 'Escaped Dollar', 132 | 'type' => 'CharType\Generic', 133 | 'pattern' => array('\$'), 134 | 'returnValue' => '$' 135 | ), 136 | array( 137 | 'name' => 'Escaped assert start', 138 | 'type' => 'CharType\Generic', 139 | 'pattern' => array('\^'), 140 | 'returnValue' => '^' 141 | ), 142 | array( 143 | 'name' => 'Escaped left square bracket', 144 | 'type' => 'CharType\Generic', 145 | 'pattern' => array('\['), 146 | 'returnValue' => '[' 147 | ), 148 | array( 149 | 'name' => 'Escaped right square bracket', 150 | 'type' => 'CharType\Generic', 151 | 'pattern' => array('\]'), 152 | 'returnValue' => ']' 153 | ), 154 | array( 155 | 'name' => 'Escaped alternative branch', 156 | 'type' => 'CharType\Generic', 157 | 'pattern' => array('\|'), 158 | 'returnValue' => '|' 159 | ), 160 | array( 161 | 'name' => 'Escaped question mark', 162 | 'type' => 'CharType\Generic', 163 | 'pattern' => array('\?'), 164 | 'returnValue' => '?' 165 | ), 166 | array( 167 | 'name' => 'Escaped zero or more quantifier', 168 | 'type' => 'CharType\Generic', 169 | 'pattern' => array('\*'), 170 | 'returnValue' => '*' 171 | ), 172 | array( 173 | 'name' => 'Escaped one or more quantifier', 174 | 'type' => 'CharType\Generic', 175 | 'pattern' => array('\+'), 176 | 'returnValue' => '+' 177 | ), 178 | array( 179 | 'name' => 'Escaped minus', 180 | 'type' => 'CharType\Generic', 181 | 'pattern' => array('\-'), 182 | 'returnValue' => '-' 183 | ), 184 | array( 185 | 'name' => 'Escaped left curly bracket', 186 | 'type' => 'CharType\Generic', 187 | 'pattern' => array('\{'), 188 | 'returnValue' => '{' 189 | ), 190 | array( 191 | 'name' => 'Escaped right curly bracket', 192 | 'type' => 'CharType\Generic', 193 | 'pattern' => array('\}'), 194 | 'returnValue' => '}' 195 | ), 196 | array( 197 | 'name' => 'Character Unknown', 198 | 'type' => 'CharType\Unknown', 199 | ), 200 | ); 201 | } 202 | 203 | /** 204 | * Gets the configuration. 205 | * 206 | * @return array 207 | */ 208 | public function getConfig() 209 | { 210 | return $this->config; 211 | } 212 | 213 | /** 214 | * Sets the configuration. 215 | * 216 | * @param array $config 217 | */ 218 | public function setConfig($config) 219 | { 220 | $this->config = $config; 221 | } 222 | 223 | /** 224 | * Setup the configuration. 225 | * 226 | * @param array $parameters 227 | * 228 | * @return ExpressionContainer 229 | */ 230 | public function setUp($parameters) 231 | { 232 | $expressions = new ExpressionContainer(); 233 | foreach ($parameters as $param) { 234 | $charType = $this->buildCharType($param); 235 | $expressions->set($charType); 236 | } 237 | 238 | return $expressions; 239 | } 240 | 241 | private function buildCharType($param) 242 | { 243 | $charTypeClass = 'RegRev\\Metacharacter\\' . $param['type']; 244 | $charType = new $charTypeClass; 245 | if (array_key_exists('chars', $param)) { 246 | $charType->setChars($param['chars']); 247 | } 248 | if (array_key_exists('pattern', $param)) { 249 | foreach ($param['pattern'] as $pat) { 250 | $charType->setPattern($pat); 251 | } 252 | } 253 | if (array_key_exists('returnValue', $param)) { 254 | $charType->setReturnValue($param['returnValue']); 255 | } 256 | 257 | return $charType; 258 | } 259 | } -------------------------------------------------------------------------------- /src/RegRev/Debug.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev; 12 | 13 | /** 14 | * Class Debug 15 | */ 16 | class Debug 17 | { 18 | /** @var array */ 19 | private static $messages = array(); 20 | 21 | /** 22 | * Sets the debug messages. 23 | * 24 | * @param string $message 25 | */ 26 | static public function setMessage($message) 27 | { 28 | self::$messages[] = $message; 29 | } 30 | 31 | /** 32 | * Gets the debug messages. 33 | * 34 | * @return array 35 | */ 36 | static public function getMessages() 37 | { 38 | return self::$messages; 39 | } 40 | 41 | /** 42 | * Clear the debug messages. 43 | */ 44 | static public function clear() 45 | { 46 | self::$messages = array(); 47 | } 48 | } -------------------------------------------------------------------------------- /src/RegRev/Exception/RegExpNotValidException.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Exception; 12 | 13 | /** 14 | * Class RegExpNotValidException 15 | * 16 | * @package RevReg\Exception 17 | */ 18 | class RegExpNotValidException extends \RuntimeException 19 | { 20 | /** 21 | * Constructor 22 | * @param string $string 23 | */ 24 | public function __construct($string) 25 | { 26 | parent::__construct(sprintf('The regular expression "%s" is not valid', $string)); 27 | } 28 | } -------------------------------------------------------------------------------- /src/RegRev/ExpressionContainer.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev; 12 | 13 | /** 14 | * Class ExpressionContainer, 15 | * handles the available regular expressions. 16 | */ 17 | class ExpressionContainer implements \Iterator 18 | { 19 | private $position = 0; 20 | 21 | private $expressions = array(); 22 | 23 | /** 24 | * Constructor. 25 | */ 26 | public function __construct() 27 | { 28 | $this->position = 0; 29 | } 30 | 31 | /** 32 | * Sets the expression. 33 | * 34 | * @param mixed $expression 35 | */ 36 | public function set($expression) 37 | { 38 | $this->expressions[] = $expression; 39 | } 40 | 41 | /** 42 | * Rewinds the container index. 43 | */ 44 | public function rewind() 45 | { 46 | $this->position = 0; 47 | } 48 | 49 | /** 50 | * Gets the current element. 51 | * 52 | * @return mixed 53 | */ 54 | public function current() 55 | { 56 | return $this->expressions[$this->position]; 57 | } 58 | 59 | /** 60 | * Returns the current key. 61 | * 62 | * @return int 63 | */ 64 | public function key() 65 | { 66 | return $this->position; 67 | } 68 | 69 | /** 70 | * Increases the current index. 71 | */ 72 | public function next() 73 | { 74 | ++$this->position; 75 | } 76 | 77 | /** 78 | * Checks if the expression is set. 79 | * 80 | * @return bool 81 | */ 82 | public function valid() 83 | { 84 | return isset($this->expressions[$this->position]); 85 | } 86 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/CharType/CharListInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\CharType; 12 | 13 | /** 14 | * Defines an interface to handle list of characters. 15 | */ 16 | interface CharListInterface 17 | { 18 | /** 19 | * Sets the character list 20 | * 21 | * @param string $charList 22 | */ 23 | public function setChars($charList); 24 | 25 | /** 26 | * Gets the character list. 27 | * 28 | * @return string 29 | */ 30 | public function getChars(); 31 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/CharType/CharType.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\CharType; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | 15 | /** 16 | * Class CharType, 17 | * handles list of characters. 18 | */ 19 | class CharType extends CharacterHandler implements CharListInterface 20 | { 21 | private $chars; 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function generate() 27 | { 28 | $randomIndex = rand(0, strlen($this->chars) -1); 29 | 30 | return $this->chars[$randomIndex]; 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | */ 36 | public function setChars($chars) 37 | { 38 | $this->chars = $chars; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function getChars() 45 | { 46 | return $this->chars; 47 | } 48 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/CharType/Generic.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\CharType; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | 15 | /** 16 | * Class Generic, 17 | * provides supported for escaped generic characters, 18 | * returns the value set via setReturnValue. 19 | */ 20 | class Generic extends CharacterHandler 21 | { 22 | private $returnValue; 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function generate() 28 | { 29 | return $this->returnValue; 30 | } 31 | 32 | /** 33 | * Sets the value should return the generate method. 34 | * 35 | * @param string $string 36 | */ 37 | public function setReturnValue($string) 38 | { 39 | $this->returnValue = $string; 40 | } 41 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/CharType/Unknown.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\CharType; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | 15 | /** 16 | * Class Unknown, 17 | * handles character not recognized by the supported expression. 18 | */ 19 | class Unknown extends CharacterHandler 20 | { 21 | private $string; 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function generate() 27 | { 28 | return $this->string; 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | public function isValid($string) 35 | { 36 | $this->string = $string[0]; 37 | 38 | return true; 39 | } 40 | 41 | /** 42 | * @return string 43 | */ 44 | public function getMatch() 45 | { 46 | return $this->string; 47 | } 48 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/CharacterHandler.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter; 12 | 13 | /** 14 | * Class CharacterHandler 15 | */ 16 | abstract class CharacterHandler 17 | { 18 | private $patterns = array(); 19 | private $match; 20 | private $successor; 21 | private $previous; 22 | private $name = null; 23 | 24 | /** 25 | * @param string $string 26 | * 27 | * @return bool 28 | */ 29 | public function isValid($string) 30 | { 31 | foreach ($this->getPatterns() as $pattern) { 32 | if (strpos($string, $pattern) === 0) { 33 | $this->match = substr($string, 0, strlen($pattern)); 34 | 35 | return true; 36 | } 37 | } 38 | 39 | return false; 40 | } 41 | 42 | /** 43 | * Gets a description of a meta char 44 | * 45 | * @return string 46 | */ 47 | public function getName() 48 | { 49 | if ($this->name !== null) { 50 | return $this->name; 51 | } 52 | 53 | return get_class($this); 54 | } 55 | 56 | /** 57 | * Sets a name for debug the class 58 | * 59 | * @param string $name 60 | */ 61 | public function setName($name) 62 | { 63 | $this->name = $name; 64 | } 65 | 66 | /** 67 | * Sets a string that identify the regular expression. 68 | * 69 | * @param string $pattern 70 | */ 71 | public function setPattern($pattern) 72 | { 73 | array_push($this->patterns, $pattern); 74 | } 75 | 76 | /** 77 | * Gets a the meta char 78 | * 79 | * @return array 80 | */ 81 | public function getPatterns() 82 | { 83 | return $this->patterns; 84 | } 85 | 86 | /** 87 | * @return string mixed 88 | */ 89 | public function getMatch() 90 | { 91 | return $this->match; 92 | } 93 | 94 | /** 95 | * @param string $match 96 | * 97 | * @return string|null 98 | */ 99 | public function setMatch($match) 100 | { 101 | $this->match = $match; 102 | } 103 | 104 | /** 105 | * Handles the generation process. 106 | * 107 | * @return string 108 | */ 109 | abstract public function generate(); 110 | 111 | /** 112 | * Sets chain successor. 113 | * 114 | * @param CharacterHandler $handler 115 | */ 116 | final public function setSuccessor(CharacterHandler $handler) 117 | { 118 | $this->successor = $handler; 119 | $this->successor->setPrevious($this); 120 | } 121 | 122 | /** 123 | * Set previous handler. 124 | * 125 | * @param CharacterHandler $handler 126 | */ 127 | final public function setPrevious(CharacterHandler $handler) 128 | { 129 | $this->previous = $handler; 130 | } 131 | 132 | /** 133 | * Gets previous handler. 134 | * 135 | * @return CharacterHandler 136 | */ 137 | final public function getPrevious() 138 | { 139 | return $this->previous; 140 | } 141 | 142 | /** 143 | * Gets the result. 144 | * 145 | * @param string $result 146 | * 147 | * @return string 148 | */ 149 | final public function getResult($result = '') 150 | { 151 | $result.= $this->generate(); 152 | if ($this->successor !== null) { 153 | return $this->successor->getResult($result); 154 | } 155 | 156 | return $result; 157 | } 158 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/GroupType/Subpattern.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\GroupType; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | use RegRev\RegRev; 15 | 16 | /** 17 | * Class Subpattern, 18 | * handles the sub-pattern match. 19 | */ 20 | class Subpattern extends CharacterHandler 21 | { 22 | const SQUARE_BRACKETS_PATTERN = '/(^\(.*\))/'; 23 | 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function isValid($string) 28 | { 29 | foreach ($this->getPatterns() as $pattern) { 30 | if (preg_match('/\[\)/', $string, $match)) { 31 | $pattern = Subpattern::SQUARE_BRACKETS_PATTERN; 32 | } 33 | if (preg_match($pattern, $string, $match)) { 34 | $this->setMatch($match[0]); 35 | 36 | return true; 37 | } 38 | } 39 | 40 | return false; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function generate() 47 | { 48 | return RegRev::generate(substr($this->getMatch(), 1, -1)); 49 | } 50 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/Quantifier/NTimes.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\Quantifier; 12 | 13 | /** 14 | * Class NTimes, 15 | * handles an N times multiple match. 16 | */ 17 | class NTimes extends OneOrMore 18 | { 19 | 20 | private $min; 21 | private $max; 22 | 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function isValid($string) 27 | { 28 | foreach ($this->getPatterns() as $pattern) { 29 | if (preg_match($pattern, $string, $match)) { 30 | $this->setMatch($match[0]); 31 | $this->setMin($match[1]); 32 | $this->setMax($match[2]); 33 | 34 | return true; 35 | } 36 | } 37 | 38 | return false; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function generate() 45 | { 46 | $quantity = $this->getMin(); 47 | 48 | if ($max = $this->getMax()) { 49 | $quantity = $this->getQuanitity($quantity, $max); 50 | } 51 | $quantity--; 52 | 53 | return $this->generateQuanitity($quantity); 54 | } 55 | 56 | /** 57 | * Sets the min quantifier. 58 | * 59 | * @param integer $min 60 | */ 61 | public function setMin($min) 62 | { 63 | $this->min = $min; 64 | } 65 | 66 | /** 67 | * Sets the max quantifier. 68 | * 69 | * @param integer $max 70 | */ 71 | public function setMax($max) 72 | { 73 | $this->max = $max; 74 | } 75 | 76 | /** 77 | * Gets the min quantifier. 78 | * 79 | * @return integer 80 | */ 81 | public function getMin() 82 | { 83 | return $this->min; 84 | } 85 | 86 | /** 87 | * Gets the max quantifier. 88 | * 89 | * @return integer 90 | */ 91 | public function getMax() 92 | { 93 | return $this->max; 94 | } 95 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/Quantifier/OneOrMore.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\Quantifier; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | 15 | /** 16 | * Class OneOrMore, 17 | * handles one or more condition. 18 | */ 19 | class OneOrMore extends CharacterHandler 20 | { 21 | /** 22 | * {@inheritdoc} 23 | */ 24 | public function generate() 25 | { 26 | $quantity = $this->getQuanitity(1, 10); 27 | 28 | return $this->generateQuanitity($quantity); 29 | } 30 | 31 | protected function getQuanitity($min, $max) 32 | { 33 | return rand($min, $max); 34 | } 35 | 36 | protected function generateQuanitity($quantity) 37 | { 38 | $result = null; 39 | for ($i = 0; $i < $quantity; $i ++) { 40 | if ($this->getPrevious()) { 41 | get_class($this->getPrevious()); 42 | $result .= $this->getPrevious()->generate(); 43 | } 44 | } 45 | 46 | return $result; 47 | } 48 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/Quantifier/ZeroOrMore.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\Quantifier; 12 | 13 | /** 14 | * Class ZeroOrMore, 15 | * handles zero or more condition. 16 | */ 17 | class ZeroOrMore extends OneOrMore 18 | { 19 | /** 20 | * {@inheritdoc} 21 | */ 22 | public function generate() 23 | { 24 | $quantity = $this->getQuanitity(0, 10); 25 | 26 | return $this->generateQuanitity($quantity); 27 | } 28 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/Quantifier/ZeroOrOne.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\Quantifier; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | 15 | /** 16 | * Class ZeroOrOne, 17 | * handles zero or one condition. 18 | */ 19 | class ZeroOrOne extends CharacterHandler 20 | { 21 | /** 22 | * {@inheritdoc} 23 | */ 24 | public function generate() 25 | { 26 | return; 27 | } 28 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/Range/Alternation.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\Range; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | use RegRev\Metacharacter\CharType\Unknown; 15 | 16 | /** 17 | * Class OneOrMore, 18 | * handles one or more condition. 19 | */ 20 | class Alternation extends CharacterHandler 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function generate() 26 | { 27 | $nullType = new Unknown(); 28 | $this->setSuccessor($nullType); 29 | 30 | return; 31 | } 32 | } -------------------------------------------------------------------------------- /src/RegRev/Metacharacter/Range/Range.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev\Metacharacter\Range; 12 | 13 | use RegRev\Metacharacter\CharacterHandler; 14 | use RegRev\Metacharacter\CharType\CharListInterface; 15 | 16 | /** 17 | * Class Range, 18 | * handles the range match. 19 | */ 20 | class Range extends CharacterHandler implements CharListInterface 21 | { 22 | /** @var string */ 23 | private $chars; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function isValid($string) 29 | { 30 | foreach ($this->getPatterns() as $pattern) { 31 | if (preg_match($pattern, $string, $match)) { 32 | $this->setMatch($match[0]); 33 | 34 | return true; 35 | } 36 | } 37 | 38 | return false; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function generate() 45 | { 46 | $match = substr($this->getMatch(), 1, -1); 47 | $resultRange = ''; 48 | $isNegation = $this->isNegation($match); 49 | $ranges = $this->getRanges($match); 50 | $resultRange .= $this->createRange($ranges); 51 | $resultRange .= $this->getSingleChars($match, $ranges); 52 | if ($isNegation) { 53 | $resultRange = $this->generateNegation($resultRange); 54 | } 55 | $randomIndex = rand(0, strlen($resultRange) - 1); 56 | 57 | return $resultRange[$randomIndex]; 58 | } 59 | 60 | /** 61 | * Checks if the range is a negation (ie:[^..]). 62 | * 63 | * @param string $match 64 | * 65 | * @return bool 66 | */ 67 | private function isNegation($match) 68 | { 69 | return $match[0] == '^'; 70 | } 71 | 72 | /** 73 | * Gets single character list from the range (ie:[a4h-]). 74 | * 75 | * @param string $match 76 | * @param array $ranges 77 | * 78 | * @return string|null 79 | */ 80 | private function getSingleChars($match, $ranges) 81 | { 82 | foreach ($ranges as $range) { 83 | $match = str_replace($range, '', $match); 84 | } 85 | $match = preg_replace('/((\\\\)(?:.))/', '', $match); 86 | 87 | return $match; 88 | } 89 | 90 | /** 91 | * Gets characters range (ie:[a-f0-9]). 92 | * 93 | * @param string $match 94 | * 95 | * @return array 96 | */ 97 | private function getRanges($match) 98 | { 99 | preg_match_all('/.-[^\\\]/', $match, $ranges); 100 | 101 | return $ranges[0]; 102 | } 103 | 104 | /** 105 | * Removes the negated character from the available chars list. 106 | * 107 | * @param string $match 108 | * 109 | * @return string 110 | */ 111 | private function generateNegation($match) 112 | { 113 | $match = str_split($match); 114 | $chars = str_split($this->getChars()); 115 | foreach ($match as $negVal) { 116 | if (($key = array_search($negVal, $chars)) !== false) { 117 | if ($negVal == '\\') { 118 | continue; 119 | } 120 | unset($chars[$key]); 121 | } 122 | } 123 | 124 | return implode('', $chars); 125 | } 126 | 127 | /** 128 | * Creates the characters ranges. 129 | * 130 | * @param array $ranges 131 | * 132 | * @return string 133 | */ 134 | private function createRange($ranges) 135 | { 136 | $rangeOfString = ''; 137 | foreach ($ranges as $range) { 138 | $rangeOfString .= implode('', range($range[0], $range[2])); 139 | } 140 | 141 | return $rangeOfString; 142 | } 143 | 144 | /** 145 | * {@inheritdoc} 146 | */ 147 | public function setChars($chars) 148 | { 149 | $this->chars = $chars; 150 | } 151 | 152 | /** 153 | * {@inheritdoc} 154 | */ 155 | public function getChars() 156 | { 157 | return $this->chars; 158 | } 159 | } -------------------------------------------------------------------------------- /src/RegRev/RegRev.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, 8 | * please view the LICENSE file that was distributed with this source code. 9 | */ 10 | 11 | namespace RegRev; 12 | use RegRev\Exception\RegExpNotValidException; 13 | 14 | /** 15 | * Class RevReg 16 | */ 17 | class RegRev 18 | { 19 | /** @var array */ 20 | private static $typesFound = array(); 21 | 22 | /** @var ExpressionContainer */ 23 | private static $expressions; 24 | 25 | /** 26 | * Generates the regular expression result. 27 | * 28 | * @param string $regExp 29 | * 30 | * @return mixed 31 | * @throws Exception\RegExpNotValidException 32 | */ 33 | static public function generate($regExp) 34 | { 35 | if (@preg_match('/'.$regExp.'/', '') === false) { 36 | throw new RegExpNotValidException($regExp); 37 | } 38 | self::bootstrap(); 39 | self::$typesFound = array(); 40 | while (strlen($regExp) > 0) { 41 | foreach (self::$expressions as $type) { 42 | if ($type->isValid($regExp)) { 43 | Debug::setMessage($type->getName() . ' ' . $type->getMatch()); 44 | self::$typesFound[] = clone $type; 45 | $lengthOfMatch = strlen($type->getMatch()); 46 | $regExp = substr($regExp, $lengthOfMatch); 47 | 48 | break; 49 | } 50 | } 51 | } 52 | 53 | return self::outPut(); 54 | } 55 | 56 | /** 57 | * Configures with default values, 58 | * if custom values are not present. 59 | */ 60 | static private function bootstrap() 61 | { 62 | if (self::$expressions === null) { 63 | $configuration = new Configuration(); 64 | $parameters = $configuration->getConfig(); 65 | self::$expressions = $configuration->setUp($parameters); 66 | } 67 | } 68 | 69 | /** 70 | * SetUp a custom configuration 71 | * 72 | * @param array $parameters 73 | */ 74 | static public function setUp($parameters) 75 | { 76 | $configuration = new Configuration(); 77 | self::$expressions = $configuration->setUp($parameters); 78 | } 79 | 80 | static private function outPut() 81 | { 82 | $typeFound = self::$typesFound[0]; 83 | $totalTypesFound = count(self::$typesFound) -1; 84 | for ($i = 0; $i < $totalTypesFound; $i++) { 85 | self::$typesFound[$i]->setSuccessor(self::$typesFound[$i+1]); 86 | } 87 | 88 | return $typeFound->getResult(); 89 | } 90 | 91 | /** 92 | * Returns debug messages. 93 | * 94 | * @return array 95 | */ 96 | static public function debug() 97 | { 98 | return Debug::getMessages(); 99 | } 100 | } 101 | --------------------------------------------------------------------------------