regex-guard/regex-guard

A wrapper that allows you to validate regular expressions and handle normally uncatchable PCRE compilation warnings

1.1.0 2014-09-17 18:04 UTC

README

Build Status Coverage Status Scrutinizer Quality Score Latest Stable Version Total Downloads License SensioLabsInsight Dependency Status Reference Status

Why?

PHP core preg_* functions do not offer any good way to validate a regular expression before usage. Some core functions return false for invalid regular expressions but they also emit uncatchable warnings.

RegexGuard is a wrapper that allows you to validate regular expressions and keep your API away from uncatchable PCRE compilation warnings.

Composer Installation

{
  "require": {
    "regex-guard/regex-guard": "~1.0"
  }
}

Through terminal: composer require regex-guard/regex-guard:~1.0 🎱

Quick Example

First grab a RegexGuard instance:

$guard = \RegexGuard\Factory::getGuard();

Validate your regex:

if($guard->isRegexValid($regexp)) {
    // valid
}
else {
    // invalid
}

And there is more...

RegexGuard API

Internally, RegexGuard instance sandboxes all preg_* functions calls and handle errors in a convenient way. All preg_* core functions are fully represented:

::isRegexValid($pattern)

Validates a given regexp. Returns true when PCRE string is valid, false otherwise:

$guard->isRegexValid('/\w{0,1}/');
// true, regex is valid

$guard->isRegexValid('/\w{1,0}/');
// false, compilation fails: quantifiers are out of order

$guard->isRegexValid('/(\w)(?2)/');
// false, compilation fails: reference to non-existent subpattern at offset 7

::validateRegexOrFail($pattern)

Validates a given regexp or throw \RegexGuard\RegexException if PCRE is invalid:

$guard->validateRegexOrFail('/(\w)(?2)/');
// throws: compilation fails: reference to non-existent subpattern at offset 7

::match($pattern, $subject, &$matches=null, $flags=0, $offset=0)

Same as preg_match but throws a \RegexGuard\RegexException when an invalid PCRE string is given:

try {
    if($regexGuard->match($pattern, $subject)) {
        // match
    } else {
        // no match
    }
} catch(\RegexGuard\RegexException $e) {
    // handle the invalid regexp
}

::matchAll($pattern,$subject,&$matches=null,$flags=?,$offset=0)

Same as preg_match_all but throws a \RegexGuard\RegexException when an invalid PCRE string is given:

try {
    $found = $regexGuard->matchAll($pattern, $subject, $matches);
    if($found) {
        foreach($matches[0] as $match) {
            //
        }
    }
} catch(\RegexGuard\RegexException $e) {
    // handle the invalid regexp
}

NOTE: $flags default value depends on your PHP version.

::filter($pattern, $subject, $limit = -1, $flags = 0)

Same as preg_filter but throws a \RegexGuard\RegexException when an invalid PCRE string is given:

try {
    $result = $regexGuard->filter($pattern, $subject);
} catch(\RegexGuard\RegexException $e) {
    // handle the invalid regexp
}

::grep($pattern, $input, $flags = 0)

Same as preg_grep but throws a RegexGuard\RegexException when an invalid PCRE string is given:

try {
    $result = $regexGuard->grep($pattern, $input);
} catch(\RegexGuard\RegexException $e) {
    // handle the invalid regexp
}

::replace($pattern, $replace, $subject, $limit=-1, &$count=null)

Same as preg_replace but throws a \RegexGuard\RegexException when an invalid PCRE string is given:

try {
    $result = $regexGuard->replace($pattern, $replacement, $subject);
} catch(\RegexGuard\RegexException $e) {
    // handle the invalid regexp
}

::split($pattern, $subject, $limit = -1, $flags = 0)

Same as preg_split but throws a \RegexGuard\RegexException when an invalid PCRE string is given:

try {
    $list = $regexGuard->split($pattern, $subject);
} catch(\RegexGuard\RegexException $e) {
    // handle the invalid regexp
}

Avoiding Exceptions

You can avoid try catch blocks by telling RegexGuard not to throw exceptions when an invalid regular expression is encountered:

$guard = \RegexGuard\Factory::getGuard()->throwOnException(false);

This can be useful to avoid verbosity when your API needs to validate regexp arguments all over the place, but you will have to be extra careful when checking results!

if(1 === $guard->match('#foo#y', 'bar')) {
// ^ strict check            ^ bad regex: Unknown modifier 'y' on line 1
}

Manual Instantiation

use RegexGuard\ErrorHandler;
use RegexGuard\Sandbox;
use RegexGuard\RegexGuard;

$guard = new RegexGuard(new Sandbox(new ErrorHandler));

Features

  • No need for @preg_match, @preg_match_all...
  • No need to use regexp to validate a given regexp or any other crappy solution
  • Aims to be 100% compatible with PHP preg_* core functions
  • Faster and more reliable than @ + preg_* calls
  • Compatible with xdebug.scream

Contribution Guide

  1. Fork regex-guard
  2. Clone forked repository
  3. Install composer dependencies $ composer install
  4. Run unit tests $ phpunit
  5. Modify code: correct bug, implement feature
  6. Back to step 4
  7. Pull request to master branch

Copyright

Copyright (c) 2014 Márcio Almada. Distributed under the terms of an MIT-style license. See LICENSE for details.