Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 扩展正则语言框架中正则语言的算法复杂性_C#_Java_Regex_Time Complexity - Fatal编程技术网

C# 扩展正则语言框架中正则语言的算法复杂性

C# 扩展正则语言框架中正则语言的算法复杂性,c#,java,regex,time-complexity,C#,Java,Regex,Time Complexity,我有一点正式语言的背景,最近我发现Java和其他语言使用的是所谓的扩展正则语言。由于我的背景,当我调用compile时,我总是假设Java等语言在后台生成DFA或转换器。因此,我一直认为无论我的正则表达式有多难看,无论我的正则表达式、Pattern.matches或类似方法在线性时间内运行多长时间。但这一假设似乎是正确的 我读到的一篇文章似乎暗示一些正则表达式是在线性时间内运行的,但我并不完全相信或信任一个人 我最终将编写自己的Java正式正则表达式库(我发现现有的正则表达式库只有GNU GPL

我有一点正式语言的背景,最近我发现Java和其他语言使用的是所谓的扩展正则语言。由于我的背景,当我调用compile时,我总是假设Java等语言在后台生成DFA或转换器。因此,我一直认为无论我的正则表达式有多难看,无论我的正则表达式、Pattern.matches或类似方法在线性时间内运行多长时间。但这一假设似乎是正确的

我读到的一篇文章似乎暗示一些正则表达式是在线性时间内运行的,但我并不完全相信或信任一个人

我最终将编写自己的Java正式正则表达式库(我发现现有的正则表达式库只有GNU GPL许可证),但与此同时,我对Java/C#regexs的时间复杂性有一些疑问。我想确保我读到的是正确的

问题:

  • 像\sRT\s这样的正式语言,Java/C中正则表达式的匹配方法会解决线性或非线性时间的成员身份问题吗
  • 一般来说,我怎么知道给定正则语言的表达式成员问题对于正则表达式来说是否是线性时间

  • 我做文本分析,发现Java正则表达式不是DFA真的令人沮丧。

    正则表达式在许多语言中作为NFA实现,以支持回溯(请参阅)。由于回溯,您可以构造对某些字符串性能很差的正则表达式(请参阅)

    就分析正则表达式以确定其性能而言,我怀疑总的来说有一种非常好的方法。您可以查找警告标志,如第二个链接示例中的复合回溯,但在某些情况下,即使这样也很难正确检测

    由于我的背景,当我调用compile for Pattern时,我总是假设在Java等语言中,它会在后台生成DFA或转换器

    这种信念在学术界很普遍。实际上,正则表达式编译不会生成DFA并执行它。我在这方面只有少量的经验;20世纪90年代,我在微软的JavaScript实现中简要地研究了正则表达式编译系统。我们选择将“正则”表达式编译成简单的特定于域的字节码语言,然后为该语言构建一个解释器

    正如您所注意到的,这可能导致重复回溯在输入长度上具有指数级的不良时间行为,但编译状态的构造在表达式大小上基本上是线性的

    让我用另外两个问题来回答你们的问题——我注意到这些是真正的问题,不是修辞性的

    1) 每个实际正则表达式对应于一个具有n个状态的NDFA。相应的DFA可能需要最多2n个状态的叠加。那么,是什么阻止了构建DFA所需的时间在病理病例中呈指数增长呢?运行时在输入中可能是线性的,但是如果运行时在模式大小上是指数的,那么基本上你只是在用一种非线性交换另一种非线性


    2) 现在所谓的“正则”表达式根本不是这样的;他们可以做括号匹配。它们对应于下推自动机,而不是不确定性有限自动机。是否有一种线性算法可以为“正则”表达式构造相应的下推自动机?

    Java的正则表达式实现使用NFA方法。 这里有一个解释得很清楚的例子

    基本上,一个写得不好但仍然正确的正则表达式可能会导致引擎性能不佳。 例如,给定表达式
    (a+a++b
    和字符串
    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。
    可能需要一段时间(取决于您的机器,从几秒钟到几分钟)才能确定没有匹配项


    NFA最糟糕的情况是几乎匹配的情况(给出的示例)。因为表达式迫使引擎探索每一条路径(有很多回溯)以确定不匹配。

    这可能是一个问题,因为我很久以前就了解了DFAs,我记得他们可以告诉你一个模式是否匹配,但是他们无法返回捕获组所需的额外信息,这些信息非常重要。捕获组是正则表达式具有“贪婪”和“不情愿”限定符的原因(即
    *
    *?
    );如果匹配的唯一目的是返回true/false,那么这些将是不相关的,并且它们与DFA无关。然而,那是几十年前的事了,我不知道自那以后DFA理论有了多少发展。@ajb你可能一直在处理简化的DFA。例如,可以使用Mealy自动机输出等效的捕获组。我相信扩展正则表达式和正式正则语言之间的唯一区别是反向引用。@hatchet我是不是建议我把它转发到那里?你可能会感兴趣。你好,谢谢你的提问。对于1)“通常”,正则表达式小于匹配的字符串。因此,按照big-O,构建用于一个匹配的DFA可能比Java的正则表达式更快。即使NFA中的状态计数大于输入字符串,当您开始每天向DFA抛出数百万个字符串时,O(2^n)构造时间也与上帝常数相形见绌。但假设我们坚持使用n个状态的NFA,成员问题仅为O(nm),其中m是输入字符串的大小。2)这来自最近的一些结果。CFG下推的两个方向都可以在线性时间和空间中完成。扩展正则表达式没有标准化。因此,对于CFG格式的正则表达式,可以在线性时间内构造PDA(假设Regex->CFG只将输入大小扩展一个常量)。但问题是,并不是所有的编程语言都有Re