Php 如何验证regex?

Php 如何验证regex?,php,regex,Php,Regex,我想在PHP中测试正则表达式的有效性,最好是在使用它之前。要做到这一点,唯一的方法就是尝试preg_match()并查看它是否返回FALSE 是否有一种更简单/正确的方法来测试有效的正则表达式?如果您想动态测试regexpreg\u match(…)===false似乎是您唯一的选择。PHP在使用正则表达式之前没有编译正则表达式的机制 您还可以找到一个有用的函数 另一方面,如果您有一个正则表达式,并且在使用它之前只想知道它是否有效,那么有很多可用的工具。我发现它很好用。我创建了一个简单的函数,可

我想在PHP中测试正则表达式的有效性,最好是在使用它之前。要做到这一点,唯一的方法就是尝试
preg_match()
并查看它是否返回
FALSE


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

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

您还可以找到一个有用的函数


另一方面,如果您有一个正则表达式,并且在使用它之前只想知道它是否有效,那么有很多可用的工具。我发现它很好用。

我创建了一个简单的函数,可以调用它来检查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();
preg_match(“/(?:\D+)*[!?]/”,“foobar foobar foobar”);
echo是_preg_error();

备选方案-正则表达式在线检测仪

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

要验证RegExp,只需在
null
上运行它(无需知道要预先测试的数据)。如果它返回显式false(
==false
),它将被破坏。否则它是有效的,尽管它不需要匹配任何内容


因此无需编写自己的RegExp验证程序。这是浪费时间…

如果不实际执行regex,您无法确定它是否有效。我最近为Zend框架实现了一个类似的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;
    }
}

您可以使用正则表达式验证您的正则表达式,并达到一定的限制。签出此以获取更多信息

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


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

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

我发现使用TDD是开发正则表达式的一种有效方法,这意味着在将来扩展它会变得简单,因为您已经拥有了所有可用的测试用例


关于设置单元测试,的答案有一个很好的答案。

根据,在使用表达式之前,没有这样的方法来测试表达式的有效性。但是我认为,如果有人使用了无效的表达式,这是该应用程序中的设计错误,而不是运行时错误,所以您应该没事。

总之,对于所有遇到这个问题的人,您可以使用这样的函数在PHP中验证正则表达式

if($error = invalidRegex('/foo//'))
{
    die($error);
}
preg_match()如果模式与给定主题匹配,则返回1;如果不匹配,则返回0;如果发生错误,则返回FALSE。-

可以这样使用

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

如果您的引擎支持递归(PHP应该支持),您可以检查它是否是语法正确的正则表达式,以及正则表达式的噩梦

但是,从算法上讲,如果不运行它,就无法判断它是否会给出您想要的结果

发件人:

(以下代码)在以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下几点以下以下以下以下以下几点以下以下以下几点以下以下以下以下几点以下以下以下几点以下以下以下以下几点以下以下以下以下几点以下以下以下以下以下几点以下以下以下以下以下以下以下以下以下以下以下几点::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除除)$/
我不确定它是否支持PCRE,但在at上有一个Chrome扩展。我自己还没有用过它,所以我不能担保,但也许它会有用

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

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

//对于PHP>=8,请使用内置的strengdswith而不是此函数。
//取自https://www.php.net/manual/en/function.str-ends-with.php#125967
函数结束($haystack,$pinder){
$length=strlen($needle);
返回$length>0?substr($haystack,-$length)==$pinder:true;
}
功能测试\u regex($regex){
预匹配($regex,NULL);
$constants=get_defined_constants(true)['pcre'];
foreach($key=>$value的常量){
如果(!endsWith($key,'.\u ERROR')){
未设置($constants[$key]);
}
}
返回数组翻转($constants)[preg_last_error()];
}

请注意,调用
preg_match()
仍然会对无效的正则表达式发出警告。可以使用自定义错误处理程序捕获警告


请参阅。

您的意思是:?如果它不必是代码,您可以访问regexr.com,粘贴到您的regex中,然后键入与之匹配的文本。为什么不检查preg_match()看起来好像我迟到了吗?一些答案不认为可能是验证的正则表达式来自一个应用程序的管理员用户的输入…也许这个应用程序有一个带有“regex”字段的“contact_types”表……只是一个猜测:OP说“我想在PHP中测试正则表达式的有效性,最好在它被使用之前测试它。”@Cyborgx37那又怎样?我给了他一个空的答案。现在不需要对要对其使用的字符串进行修改。你只需要知道模式,看看它是否正确。是否匹配。。。这是一个不同的故事,取决于您的目标字符串。我说错了什么?我没有投你反对票。。。猜猜为什么有人会这么做。我认为你的答案很好。注意,在一个无效的regexp的情况下,你的代码将显示一个警告,这是
if($error = invalidRegex('/foo//'))
{
    die($error);
}
/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/