我如何验证正则表达式?

时间:2010-12-14 15:17:21

标签: php regex

我想在PHP中测试正则表达式的有效性,最好在它使用之前。实际执行此操作的唯一方法是preg_match()并查看它是否返回FALSE吗?

是否有更简单/正确的方法来测试有效的正则表达式?

11 个答案:

答案 0 :(得分:125)

// This is valid, both opening ( and closing )
var_dump(preg_match('~Valid(Regular)Expression~', null) === false);
// This is invalid, no opening ( for the closing )
var_dump(preg_match('~InvalidRegular)Expression~', null) === false);

正如用户 pozs 所说,也考虑在测试环境中将@放在preg_match()@preg_match())前面以防止警告或通知。

要验证RegExp,只需针对null 运行它(无需知道您要预先测试的数据)。如果它返回显式的false(=== false),它就会被破坏。否则它是有效的,虽然它不需要匹配。

所以没有必要编写自己的RegExp验证器。 浪费时间......

答案 1 :(得分:22)

我创建了一个简单的函数,可以调用preg

function is_preg_error()
{
    $errors = array(
        PREG_NO_ERROR               => 'Code 0 : No errors',
        PREG_INTERNAL_ERROR         => 'Code 1 : There was an internal PCRE error',
        PREG_BACKTRACK_LIMIT_ERROR  => 'Code 2 : Backtrack limit was exhausted',
        PREG_RECURSION_LIMIT_ERROR  => 'Code 3 : Recursion limit was exhausted',
        PREG_BAD_UTF8_ERROR         => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
        PREG_BAD_UTF8_OFFSET_ERROR  => 'Code 5 : Malformed UTF-8 data',
    );

    return $errors[preg_last_error()];
}

您可以使用以下代码调用此函数:

preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
echo is_preg_error();

替代方案 - 正则表达式在线测试程序

答案 2 :(得分:15)

如果您想动态测试正则表达式preg_match(...) === false似乎是您唯一的选择。 PHP没有在使用前编译正则表达式的机制。

你也可以发现preg_last_error是一个有用的功能。

另一方面,如果你有一个正则表达式,只是想在使用之前知道它是否有效,那么就有很多工具可用。我发现rubular.com使用起来很愉快。

答案 3 :(得分:6)

如果您的引擎支持递归(PHP应该),您可以检查它是否是正则规则正确的正则表达式,这是一个正则表达式的噩梦。

但是,如果不运行它,您无法通过算法判断它是否会提供您想要的结果。

来自:Is there a regular expression to detect a valid regular expression?

/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/

答案 4 :(得分:2)

如果没有实际执行正则表达式,您无法确定它是否有效。我最近为Zend Framework实现了一个类似的RegexValidator。工作得很好。

<?php
class Nuke_Validate_RegEx extends Zend_Validate_Abstract
{
    /**
     * Error constant
     */
    const ERROR_INVALID_REGEX = 'invalidRegex';

    /**
     * Error messages
     * @var array
     */
    protected $_messageTemplates = array(
        self::ERROR_INVALID_REGEX => "This is a regular expression PHP cannot parse.");

    /**
     * Runs the actual validation
     * @param string $pattern The regular expression we are testing
     * @return bool
     */
    public function isValid($pattern)
    {
        if (@preg_match($pattern, "Lorem ipsum") === false) {
            $this->_error(self::ERROR_INVALID_REGEX);
            return false;
        }
        return true;
    }
}

答案 5 :(得分:1)

您可以使用正则表达式达到某个限制来验证正则表达式。查看此stack overflow answer了解详情。

注意:“递归正则表达式”不是正则表达式,此正则表达式的扩展版本与扩展正则表达式不匹配。

更好的选择是使用preg_match并与NULL匹配为@Claudrian said

答案 6 :(得分:1)

总而言之,对于所有遇到此问题的人,您可以使用类似这样的函数验证PHP中的正则表达式。

  

如果模式与给定主题匹配,则preg_match()返回1,否则返回0;如果发生错误,则返回FALSE。 - PHP Manual

/**
 * Return an error message if the regular expression is invalid
 *
 * @param string $regex string to validate
 * @return string
 */
function invalidRegex($regex)
{
    if(preg_match($regex, null) !== false)
    {
        return '';
    }

    $errors = array(
        PREG_NO_ERROR               => 'Code 0 : No errors',
        PREG_INTERNAL_ERROR         => 'Code 1 : There was an internal PCRE error',
        PREG_BACKTRACK_LIMIT_ERROR  => 'Code 2 : Backtrack limit was exhausted',
        PREG_RECURSION_LIMIT_ERROR  => 'Code 3 : Recursion limit was exhausted',
        PREG_BAD_UTF8_ERROR         => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
        PREG_BAD_UTF8_OFFSET_ERROR  => 'Code 5 : Malformed UTF-8 data',
    );

    return $errors[preg_last_error()];
}

可以这样使用。

if($error = invalidRegex('/foo//'))
{
    die($error);
}

答案 7 :(得分:1)

我不确定它是否支持PCRE,但https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib上有一个名为RegExp Tester的Chrome扩展程序。我还没有使用它,所以我不能保证它,但它可能有用吗?

答案 8 :(得分:0)

我倾向于为你的正则表达式设置一些单元测试。这样,您不仅可以确保正则表达式确实有效,而且还可以在匹配时有效。

我发现使用TDD是开发正则表达式的有效方法,并且意味着将来扩展它正在简化,因为您已经拥有了所有的测试用例。

this question的答案在设置单元测试方面有很好的答案。

答案 9 :(得分:0)

您应尝试将正则表达式与NULL相匹配。如果结果为FALSE(=== FALSE),则错误。

在PHP> = 5.5中,您可以使用以下代码自动获取内置错误消息,而无需定义自己的函数即可获取它:

preg_match($regex, NULL);
echo array_flip(get_defined_constants(true)['pcre'])[preg_last_error()];

答案 10 :(得分:-3)

根据PCRE reference,没有这种方法来测试表达式的有效性,之前使用它。但我认为,如果有人使用无效表达式,那么该应用程序中的设计错误,而不是运行时错误,所以你应该没问题。