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

问题描述 投票:8回答:1

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

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

我想在Perl的风格中使用backrefs和递归调用,但无法使cross-serial dependencies工作(即,无法反转捕获的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)(?!))

(点击here进行测试。)

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

致谢:我确实理解将这种构造与正则表达式相匹配并不是一个好主意。我正在做这方面的研究工作,我想知道是否有可能。如果是的话,please do not use it in production code

regex
1个回答
1
投票

由于您的主要问题是“是否可以使用正则表达式”,我想首先分享我最喜欢的正则表达式信息网站。具体来说,How does the regex engine work?学习将让你更好地了解正则表达式是如何工作的,以及为什么试图走出它非常明确的方框很快就会变成破碎的灵魂和CPU。

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

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

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

对于模式的有限数量的排列,足够长的正则表达式可以匹配任何东西。 (正则表达式的长度可能是灵魂/ CPU破碎,但技术上可行)

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

所以,你需要问自己2个问题

  1. 是否有一些我想要匹配的有限数量的排列?
  2. 我的灵魂/ CPU会在这样的正则表达式中存活吗?

相关的,你应该读一读Nondeterministic finite automaton。由于您要求研究原因,并且任何纯正则表达式引擎都是NDFA,因此有必要知道它们受到相同的已知限制。

TL:DR;

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

实际上,是的,但是以牺牲灵魂为代价。 从理论上说,不,一点也不。永远都会有一个有效的案例,你的正则表达式会失败。

© www.soinside.com 2019 - 2024. All rights reserved.