是否可以将多个heredoc表达式与正则表达式匹配?

时间:2016-07-31 20:11:43

标签: regex

是否有任何正则表达式引擎可以匹配表达式上的多个heredoc字符串?例如,正如人们用Ruby写的那样:

f <<FOO, 10, <<BAR, 20
some text
FOO
some more text
BAR

我想在Perl的风格中使用backrefs和递归调用,但无法使cross-serial dependencies工作(即,无法反转捕获的backrefs,因为{ {1}}应该在FOO之前匹配。我还考虑在.Net上平衡组,我强烈可以强调使用前瞻(我知道,这是一个可怕的黑客)来反转堆栈,如下所示:

BAR

(点击here进行测试。)

匹配(?:(?<x>foo|bar|baz)|\s)+(?(x)|(?!))\s*(?(x)(?=(.*?)(?<-x>(?<y>\k<x>)))){3}(?(x)(?!))(?:(?(y)(?<-y>\k<y>))|\s)+(?(x)(?!))(?(y)(?!)) ,但之后我必须添加一个手动计数器(foo bar baz foo bar baz),因为前瞻不会与{3}重复,因为它没有#{1}}。消耗我假设的任何输入。因此,这不会对任意案件起作用(但它很接近!)。当然,我可以用+或任何其他大数字代替,这可以回答我的问题,但我想知道是否还有其他方法。

确认:我明白将这种类型的构造与正则表达式相匹配并不是一个好主意。我正在做 research 工作,我想知道它是否可能。如果是,please do not use it in production code

1 个答案:

答案 0 :(得分:1)

由于您的主要问题是“正则表达式是否可能”,因此,我想首先分享我最喜欢的正则表达式信息网站。具体来说,How does the regex engine work?的学习将使您更好地了解正则表达式的工作原理,以及为何试图摆脱其定义明确的框框的原因,很快就会演变成破碎的灵魂和CPU。

关键要点在于,正则表达式引擎在任何时候都只有2条信息。

  1. 我要匹配什么令牌?
  2. 字符串中的下一个标记是什么?

这很容易忘记,因为与蒸汽解析不同,正则表达式引擎在匹配失败时会回溯(通常会做很多事情)。而且CPU的速度足够快,每秒可能会导致数百万次故障!尽管Regex可能具有更多的内存,因为它可以匹配“ dog之后的第一只猫”,但它只知道看到了“ dog”一词,因为它当前正在cat中查找c。或换句话说,只有满足特定的先决条件,当前状态才可能。

使用有限数量的模式排列,足够长的正则表达式可以匹配任何内容。 (该正则表达式的长度可能会使灵魂/ CPU崩溃,但在技术上是可能的)

模式不是有限的,例如“匹配数量a后跟相等数量的b”(例如,“ ab”,“ aabb”,“ aaabbb”等)。没有一种机制可以记住它已经看到了多少个a,因此它不知道要匹配多少个b。您可以通过尝试匹配所有变体(ab|aabb|aaabbb|aaaabbbb|...)来解决此问题,但是解析起来非常昂贵,而且由于我总是可以再添加一个Ab对,因此您将无法捕获每个有效输入。

实际上,您需要问自己两个问题

  1. 我想匹配的排列是否有限?
  2. 我的灵魂/ CPU能否在这种正则表达式中生存?

相关,您可能应该阅读Nondeterministic finite automaton。由于您出于研究原因而询问,并且任何纯正则表达式引擎都是NDFA,因此有助于了解它们遭受相同的已知限制。

TL:DR;

使用纯正则表达式引擎...

实际上是的,但是要付出灵魂的代价。
从理论上讲,不,完全没有。您的正则表达式总是会失败。