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

pau*_*ens 8 regex

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

f <<FOO, 10, <<BAR, 20
some text
FOO
some more text
BAR
Run Code Online (Sandbox Code Playgroud)

我想在Perl的风格中使用backrefs和递归调用,但无法设法使交叉序列依赖项工作(即,无法反转捕获的backrefs,因为FOO之前应匹配BAR).我还想过在.Net上平衡组,我可以通过使用前瞻反转堆栈(我知道,这是一个可怕的黑客),像这样:

(?:(?<x>foo|bar|baz)|\s)+(?(x)|(?!))\s*(?(x)(?=(.*?)(?<-x>(?<y>\k<x>)))){3}(?(x)(?!))(?:(?(y)(?<-y>\k<y>))|\s)+(?(x)(?!))(?(y)(?!))
Run Code Online (Sandbox Code Playgroud)

(点击这里进行测试.)

这匹配foo bar baz foo bar baz,但后来我必须添加一个手动计数器({3}),因为前瞻不会重复,+因为它不消耗我假设的任何输入.因此,这对任意案件都不起作用(但它很接近!).当然,我可以用{1000}任何其他大数字替换它,这将回答我的问题,但我想知道是否还有其他方法.

致谢:我确实理解将这种构造与正则表达式相匹配并不是一个好主意.我正在做这方面的研究工作,我想知道是否有可能.如果是,请不要在生产代码中使用它.

Tez*_*zra 3

由于您的主要问题是“正则表达式是否可行”,我想首先分享我最喜欢的正则表达式信息网站。具体来说,正则表达式引擎如何工作?学习这将使您更好地了解正则表达式是如何工作的,以及为什么试图走出它定义明确的框很快就会陷入破碎的灵魂和 CPU。

但关键的一点是,在任何时候,正则表达式引擎都只有两条信息。

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

这很容易被忘记,因为与 steam 解析不同,正则表达式引擎在匹配失败时可以回溯(它通常会做很多事情)。CPU 的速度足够快,每秒可能会失败数百万次!虽然正则表达式可能看起来有更多的内存,因为它可以匹配“狗之后的第一只猫”,但它只知道它已经看到了单词狗,因为它当前正在寻找猫中的c。或者换句话说,当前状态只有在满足特定前提条件时才可能出现。

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

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

所以说真的,你需要问自己两个问题

  1. 我想要匹配的排列数量是否有限?
  2. 我的灵魂/CPU 能承受这样的正则表达式吗?

相关的,您可能应该阅读非确定性有限自动机。由于您询问的是研究原因,并且任何纯正则表达式引擎都是 NDFA,因此了解它们遭受相同的已知限制会有所帮助。

TL:博士;

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

实际上,是的,但代价是灵魂。
从理论上讲,不,一点也不。您的正则表达式总会有失败的情况。