正则表达式的正则表达式?

dat*_*.io 9 php regex

可能重复:
是否有正则表达式来检测有效的正则表达式?
正则表达式用于查找正则表达式?

我有一个应用程序,使用户能够输入正则表达式.如何检查正则表达式的任何输入并确保它们是有效的,因为如果它们不存在则会出现preg_match错误?

我不想在preg_match之前使用'@',所以如果有办法检查正则表达式的用户输入的有效性,那就太好了.

PHP的正则表达式系统对我来说似乎太复杂了,无法为它们提供正则表达式.

dio*_*ziz 30

在数学上,使用正则表达式验证正则表达式是不可能的.这是因为(正式)正则表达式只能识别常规语言.语言是任何字符串.例如,所有十进制数的集合是一种语言(可以使用正则表达式来描述); 所有有效正则表达式的集合也是一种语言.常规语言是仅需要识别固定有限存储器(不是输入大小的函数)的语言.

包含所有有效正则表达式的语言不是常规语言; 因此,使用正则表达式识别正则表达式是不可能的.

要理解这一点,请注意正则表达式中包含必须匹配的括号.因此,如果"("已经发生,则")"必须在以后发生.使用仅具有固定有限内存的机器无法描述这一点.因为,如果一个办法做到这一点,你的正则表达式具有有限内存ķ不同状态(一些整数K),其中K开口的expression括号后面跟着K右括号,虽然有效的正则表达式会一直无法被该机器识别 - 这是一个矛盾(注意,在形式语言中,我们的假设是文本处理一次出现一个字符,从左到右,对于应用的正则表达式是相同的).我们将描述正则表达式的语言称为无上下文而非常规语言.

(使用抽取引理证明正则表达式不能形成常规语言是微不足道的)

因此,使用正则表达式识别正则表达式存在一个基本的计算机科学问题:在数学上不可能这样做.

有限状态自动机可以识别常规语言,即具有有限状态但没有记忆的机器.要解决您的问题,您需要添加一些取决于输入大小的内存.正则表达式,因为它们是无上下文的(幸运的是它们不是一些模糊的,难以识别的语言类型)可以使用下推自动机在线性时间中识别.这是一个"for"循环,它一次通过表达一个标记(通常是一个字符)的表达式,并跟踪它在堆栈上看到的内容,即它"推送"它在第一个中输入"pops"的数据弹出时尚.(推送到堆栈的数据示例:"我需要记住找到匹配的`)'以后!"; 你可以根据需要多次"推"这个; 你可以稍后"弹出"它,当你需要检查你是否真的需要先匹配一个左括号时).

当然,为正则表达式编写自己的识别引擎会有点开销 - 但如果你想这样做,你应该知道上述限制.使用已有的机制来做这件事更明智 - 我怀疑你可以把这份工作交给正则表达式库或者更热衷于处理正则表达式的语言,比如Perl; 但是@ -method听起来并不是一个想法太糟糕了:它可能很慢,但你的用户可能会输入非常慢的正则表达式; 这可能是一种不好的做法,但在您的情况下,它似乎是最好的解决方案.

维基百科中的一些相关文章:

我希望这有帮助!

  • +1:答案很长,但这是唯一正确的答案.PCRE中的正则表达式语法是一种无上下文的语言.另外:考虑将您的文章引用链接到维基百科本身:-)(对不起,如果我错过了忍者编辑,你已经在这里做了) (3认同)

cly*_*yfe 10

preg_match()FALSE 如果发生错误则返回.

  1. 将表达式发送到服务器
  2. preg_match 在一个空字符串上
  3. 看看是否发生错误

您可以使用Ajax来验证实时,也可以在表单提交后进行验证.
你也可以尝试通过将表达式提供给javascript regexp引擎进行验证,但是js regexp语法与php的语法不是100%兼容.

  • 确保使用类型安全的比较:`preg_match(...)=== false`. (3认同)

geo*_*car 6

让用户提交正则表达式几乎肯定是一个坏主意.

有些表达非常昂贵.试试这个:

preg_match('/(.*){1,32000}[bc]/','aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
Run Code Online (Sandbox Code Playgroud)

这只是输入的30个字符!它们看起来都不/^(?:(\d+)|::)*$/是这样: 在PCRE中也是指数时间.