Validates that the value of a field matches a Regular Expression.
@param $pattern
@param null $flags
@return $this
438431
function regexp($pattern, $flags = null) {
        $regexp['pattern'] = $pattern;
        if ($flags) $regexp['flags'] = $flags;
        $this->data['regexp'] = $regexp;
        return $this;
    }
924856
public function match($pattern)
    {
        if (!is_string($pattern)) {
            throw new InvalidStringException('pattern', $pattern);
        } elseif (empty($pattern)) {
            throw new InvalidNotEmptyException('pattern');
        }

        if (!is_string($this->value)) {
            throw new InvalidStringException($this->name, $this->value);
        }

        // God please sorry for this @
        $checkResult = @preg_match($pattern, $this->value);

        if ((preg_last_error() !== PREG_NO_ERROR) || ($checkResult === false)) {
            throw new InvalidRegExpPatternException('pattern', $pattern);
        }

        if ($checkResult === 0) {
            throw new StringNotMatchRegExpException($this->name, $this->value, $pattern);
        }

        return $this;
    }
510677
protected static function systemGlob($pattern, $flags)
    {
        ErrorStack::handleError();
        $res = glob($pattern, $flags);
        $err = ErrorStack::handleDone();
        if ($res === false)
            throw new \RuntimeException("glob('{$pattern}', {$flags}) failed", 0, $err);

        return $res;
    }
947932
public function pregValues($pattern, $defaultResult = null, $flags = 0)
    {
        $result = preg_grep($pattern, array_values($this->target), $flags);

        return $result ? array_values($result) : $defaultResult;
    }
709312
public function whereRegex($field, $regex, $flags = '')
    {
        foreach ($this->queries as $query) {
            $query->whereRegex($field, $regex, $flags);
        }

        return $this;
    }
369802
public static Pattern createPattern(final String pattern, final int flags) {
        if (pattern == null) {
            LOGGER.debug("Pattern cannot be null");
            return MATCH_NOTHING_PATTERN;
        }
        try {
            return Pattern.compile(pattern, flags);
        } catch (final PatternSyntaxException exception) {
            LOGGER.debug("Pattern [{}] is not a valid regex.", pattern);
            return MATCH_NOTHING_PATTERN;
        }
    }
802677
public function matchHost($pattern, &$matches = null, $flags = 0, $offset = 0)
	{
		return preg_match($pattern, $this->_host ?: '', $matches, $flags, $offset);
	}
1274071
public function vPhone(String $pattern = NULL)
    {
        return $this->setJavascriptValidation('ZNValidationPhone', 'phone', ['phone' => $pattern], [Base::presuffix($pattern, '\'')]);
    }
1263388
public function regexp($pattern, $msg)
    {
        if(!preg_match($pattern, (string)$this->_value)) {
            $this->_errors[] = $msg;
        }
        return $this;
    }
1286132
public function setPattern($pattern)
    {
        if (!\Erebot\Utils::stringifiable($pattern)) {
            throw new \Erebot\InvalidValueException('Pattern must be a string');
        }

        $this->pattern = $pattern;
    }
850574
public function matching ($pattern, &$matches = [], $flags = 0, $offset = 0, $start = 0, $end = null) {
		if (is_null($end)) {
			$end = $this->_length;
		}
		return static::Match($pattern, static::Substring($this->_string, $start, $end), $matches, $flags, $offset);
	}
545412
private function _regexMatch(string $pattern, int &$offset)
    {
        $idx = $offset;
        if (!preg_match($pattern, substr($this->_dn, $idx), $match)) {
            return null;
        }
        $idx += strlen($match[0]);
        $offset = $idx;
        return end($match);
    }
1055744
public function match($pattern) {
        if (!$this->_isValid) {
            return $this;
        }
        if (!preg_match($pattern, $this->_unsafeVar)) {
            $this->_isValid = false;
        }
        return $this;
    }
490085
public function match($pattern, array $patterns = []) {
        return $this->matcher->match(
            $this->addLeadingSlash($pattern), $this->getPath(), $patterns
        );
    }
36679
protected function validatePattern($pattern)
    {
        if (!preg_match('/(?<modifier>[imsxeADSUXJu]+)$/', $pattern, $matches)) {
            return true;
        }

        if (false !== strstr($matches['modifier'], 'e')) {
            throw new Exception\InvalidArgumentException(sprintf(
                'Pattern for a PregReplace filter may not contain the "e" pattern modifier; received "%s"',
                $pattern
            ));
        }
    }
1159647
public function getMatchAll(string $pattern, int $flags = PREG_PATTERN_ORDER, int $offset = 0)
	{
		return preg_match_all($pattern, $this->str, $matches, $flags, $offset) === false ? null : $matches;
	}
1081855
private static function PrepareRegexPattern( $pattern, $flagString )
	{

		// Check the pattern does not include a back-reference in a character class
		$result = preg_match( "/\[.*?\\\\\d+.*?\]/", $pattern );
		if ( $result )
		{
			throw XPath2Exception::withErrorCodeAndParam( "FORX0002", Resources::InvalidRegularExpr, "$pattern/$flagString" );
		}

		// If one of the flags is x then need to remove whitespace not in character classes
		// PCRE will not remove escaped spaces when the x flag is used but XPath expects them to be removed
		if ( strpos( $flagString, "x" ) !== false )
		{
			$results = preg_match_all( "/((?<expr>[^[]*)(?<chars>\[.*?\])?)/", $pattern, $matches );
			for ( $i = 0; $i < $results; $i++ )
			{
				$match = $matches['expr'][ $i ];
				if ( empty( $match) ) continue;
				$result = preg_replace( "/((?![\r\n])\s)+/", "", $match );
				if ( $match == $result ) continue;
				$pattern = str_replace( $match, $result, $pattern );
			}
		}

		// If there is a back-reference need to add an empty comment to separate the
		// back-reference number from any following digit(s) and repeat for all back-references
		// $groups = substr_count( $pattern, "(" );
		// This pattern counts the parentheses that are not escaped by just one backslash (two is OK)
		$groups = preg_match_all( '/\\\\\\\\\(|\((?<!\\\\\()/', $pattern );
		if ( $groups )
		{
			// Get a list of all the back reference numbers
			$result = preg_match_all( "/\\\\(\d(\d?))*/", $pattern, $matches );
			if ( $result )
			{
				// $result2 = preg_match_all( "/\((([^()]+)|(?R))*\)/", $pattern, $parens );

				// Grab the valid values
				$values = array();
				foreach ( array_filter( $matches[1] ) as $key => $match )
				{
					$potentialValues = array();
					while ( strlen( $match ) > 0 )
					{
						$potentialValues[] = $match;
						$match = substr( $match, 0, strlen( $match ) - 1 );
					}

					sort( $potentialValues );
					$error = false;
					while ( count( $potentialValues ) )
					{
						$value = array_pop( $potentialValues );

						// Find the match(es) in the string and count the number of opening parentheses until that point
						$pos = strpos( $pattern, $value );

						// $matchgroupsOpen = substr_count( $pattern, "(", 0, $pos );
						// This horrible list of backslashes occurs because the regex escape char is \ and the same for PHP.
						// So every real backslash has to be quadrupled. Here's what the regex will look like outside PHP
						// 	/\\\\\(|\((?<!\\\()/
						$matchgroupsOpen = preg_match_all( '/\\\\\\\\\(|\((?<!\\\\\()/', substr( $pattern, 0, $pos ) );

						// If there are no groups throw an exception
						$error = ! $matchgroupsOpen || $matchgroupsOpen < $value;

						if ( ! $error )
						{
							// $matchgroupsClosed = substr_count( $pattern, ")", 0, $pos );
							$matchgroupsClosed = preg_match_all( '/\\\\\\\\\)|\)(?<!\\\\\))/', substr( $pattern, 0, $pos ) );

							// If reference is in a capture group its an error
							$error = ! $matchgroupsClosed || $matchgroupsClosed != $matchgroupsOpen || $matchgroupsClosed < $value;

							if ( $error ) continue;
							// This is the longest number
							$values[] = $value;
							break;
						}
					}

					if ( $error )
					{
						throw XPath2Exception::withErrorCode( "FORX0002", Resources::FORX0002 );
					}
				}

				// Make sure the back-reference numbers are valid given the list of capture groups available
				$validValues = array_intersect( $values, range( 1, $groups ) );

				// Sort them in descending order so the longest number is handled first.
				// This way \1 and \11 are handled correctly.
				// BMS Not sure this is necessary.
				rsort( $validValues );
				foreach ( $validValues as $value )
				{
					// Replace the number but only if the number is not already followed by an empty comment
					$pattern = preg_replace( "/\\\\($value)(?!\d?\(\?\#\))/", "\\\\$1(?#)", $pattern );
				}
			}
		}

		// Check to see if there are any character classes that specify character subtraction
		// If so, convert to a negative lookahead
		$results = preg_match_all( "/\[(?<chars>((.*)?(.-.))+)-(?<sub>\[(.*|.*?(.-.))+\])\]/", $pattern, $matches );
		if ( $results )
		{
			for ( $i = 0; $i < $results; $i++ )
			{
				$chars = $matches['chars'][ $i ];
				$sub = $matches['sub'][ $i ];
				$x = "(?!$sub)[$chars]";

				$pattern = str_replace( $matches[ $i ], $x, $pattern );
			}
		}

		// Replace common unicode character classes
		$pattern = str_replace( "{IsBasic", "{", $pattern );

		return $pattern;
	}