是否可以用另一个正则表达式检测一个有效的正则表达式?如果是这样,请给出下面的示例代码。


当前回答

有了这个版本,你可以用php检查一个字符串的regex -我从上面的例子,并修改了一点:

$re = '/((?:(?:[^?+*{}()[\]\\\\|]+|\\\\.|\[(?:\^?\\\\.|\^[^\\\\]|[^\\\\^])(?:[^\]\\\\]+|\\\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d*(?:,\d*)?\})[?+]?)?|\|)*)/';
$str = '[0-9]{1,}[a-z]';

preg_match($re, $str, $matches, PREG_OFFSET_CAPTURE, 0);

$length = strlen($str);
$length2 = strlen($matches[0][0]);

if($length == $length2) {

   echo "is regex";

} else {

   echo "is no regex";

}

其他回答

虽然完全可以使用MizardX发布的递归正则表达式,但对于这种事情,解析器更有用。正则表达式最初用于常规语言,递归或具有平衡组只是一个补丁。

定义有效正则表达式的语言实际上是一种与上下文无关的语法,您应该使用适当的解析器来处理它。下面是一个大学项目的示例,用于解析简单的正则表达式(没有大多数构造)。它使用JavaCC。是的,注释是西班牙语,尽管方法名是不言自明的。

SKIP :
{
    " "
|   "\r"
|   "\t"
|   "\n"
}
TOKEN : 
{
    < DIGITO: ["0" - "9"] >
|   < MAYUSCULA: ["A" - "Z"] >
|   < MINUSCULA: ["a" - "z"] >
|   < LAMBDA: "LAMBDA" >
|   < VACIO: "VACIO" >
}

IRegularExpression Expression() :
{
    IRegularExpression r; 
}
{
    r=Alternation() { return r; }
}

// Matchea disyunciones: ER | ER
IRegularExpression Alternation() :
{
    IRegularExpression r1 = null, r2 = null; 
}
{
    r1=Concatenation() ( "|" r2=Alternation() )?
    { 
        if (r2 == null) {
            return r1;
        } else {
            return createAlternation(r1,r2);
        } 
    }
}

// Matchea concatenaciones: ER.ER
IRegularExpression Concatenation() :
{
    IRegularExpression r1 = null, r2 = null; 
}
{
    r1=Repetition() ( "." r2=Repetition() { r1 = createConcatenation(r1,r2); } )*
    { return r1; }
}

// Matchea repeticiones: ER*
IRegularExpression Repetition() :
{
    IRegularExpression r; 
}
{
    r=Atom() ( "*" { r = createRepetition(r); } )*
    { return r; }
}

// Matchea regex atomicas: (ER), Terminal, Vacio, Lambda
IRegularExpression Atom() :
{
    String t;
    IRegularExpression r;
}
{
    ( "(" r=Expression() ")" {return r;}) 
    | t=Terminal() { return createTerminal(t); }
    | <LAMBDA> { return createLambda(); }
    | <VACIO> { return createEmpty(); }
}

// Matchea un terminal (digito o minuscula) y devuelve su valor
String Terminal() :
{
    Token t;
}
{
    ( t=<DIGITO> | t=<MINUSCULA> ) { return t.image; }
}

不太可能的。

用try. catch或你的语言提供的任何方法来评估它。

你可以将regex提交给preg_match,如果regex无效,preg_match将返回false。不要忘记使用@来抑制错误消息:

@preg_match($regexToTest, '');

如果正则表达式为//,则返回1。 如果正则表达式没问题,将返回0。 否则将返回false。

不,如果你使用标准正则表达式。

原因是您不能满足常规语言的抽运引理。抽吸引理指出,属于语言“L”的字符串是正则的,如果存在一个数字“N”,使得将字符串分为三个子字符串x, y, z,使得|x|>=1 && |xy|<=N,你可以重复y多次,而整个字符串仍然属于L。

抽运引理的一个结果是,你不能有A ^Nb^Mc^N这样的正则字符串,也就是说,两个相同长度的子字符串被另一个字符串隔开。无论你以何种方式将这些字符串分割成x、y和z,你都不能在不获得“a”和“c”数量不同的字符串的情况下“抽取”y,从而保留原始语言。例如,正则表达式中的圆括号就是这种情况。

在Javascript中:

SyntaxError

在传递无效正则表达式以求值时引发。

// VALID ONE
> /yes[^]*day/
Out: /yes[^]*day/

// INVALID ONE
> /yes[^*day/
Out: VM227:1 Uncaught SyntaxError: Invalid regular expression: missing /

下面是检查正则表达式字符串是否有效的函数:

步骤1:正则表达式解析器

var RegexParser = function(input) {

    // Parse input
    var m = input.match(/(\/?)(.+)\1([a-z]*)/i);

    // Invalid flags
    if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) {
        return RegExp(input);
    }

    // Create the regular expression
    return new RegExp(m[2], m[3]);
};

步骤2:使用解析器

var RegexString = "/yes.*day/"

var isRegexValid = input => {
 try {
 const regex = RegexParser(input);
 }
 catch(error) {
   if(error.name === "SyntaxError") 
    {
      return false;
    }
    else 
    {
     throw error;
    }
 }
 return true;
}