当前位置: 首页 > 知识库问答 >
问题:

是否可以擦除已匹配的捕获组,使其不参与?

司徒宇
2023-03-14
^(?:(z)?(?(1)aa|a)){2}

当输入字符串zaazaa时,它将根据需要匹配整个字符串。但当馈入zaaaa时,我希望它与zaaa匹配;相反,它匹配zaaaa,即整个字符串。(这只是为了说明。当然,此示例可以由^(?:ZAAA){2}处理,但这并不重要。捕获组擦除的实际用法往往是在循环中,而这些循环通常执行的迭代次数远远超过2次。)

另一种方法也不是理想的:

^(?:(?:z()|())(?:\1aa|\2a)){2}

请注意,当循环“展开”时,这两种方法都可以正常工作,因为它们不再需要擦除已经执行的捕获:

^(?:(z)?(?(1)aa|a))(?:(z)?(?(2)aa|a))
^(?:(?:z()|())(?:\1aa|\2a))(?:(?:z()|())(?:\3aa|\4a))

因此不能使用最简单的条件形式,而必须使用更复杂的条件形式,这只在本例中起作用,因为z的“true”匹配是非空的:

^(?:(z?)(?(?!.*$\1)aa|a)){2}

或仅使用模拟条件:

^(?:(z?)(?:(?!.*$\1)aa|(?=.*$\1)a)){2}

我已经浏览了我能找到的所有文档,似乎甚至没有提到或明确描述这种行为(在循环中捕获的内容在循环的迭代中持续存在,即使它们未能被重新捕获)。

\b(?:a()|e()|i()|o()|u()|\w)++\1\2\3\4\5\b
^(?:(?=a|(b)).(?(1)_))*$

需要明确的是:只要有充分的研究和(或)引用资料的支持,说明这在任何主流引擎中都不可能的答案是可以接受的。如果回答说这是可能的,说明起来会容易得多,因为它只需要一个例子。

关于什么是非参与式捕获组的一些信息:
http://blog.stevenlevithan.com/archives/npcg-javascript-这是最初向我介绍这个想法的文章。
https://www.regular-expressions.info/backref2.html-本页的第一部分给出了简要的解释。
在ECMAScript/javascript regexes中,对npcg的反向引用总是匹配的(进行零长度匹配)。在几乎所有其他的正则表达式中,它们都不能匹配任何东西。

共有1个答案

轩辕乐邦
2023-03-14

这在.NET的正则表达式中是部分可行的。

首先要注意的是.NET记录给定捕获组的所有捕获,而不仅仅是最新的捕获。例如,^(?=(.)*)将第一行中的每个字符记录为组中的单独捕获。

要实际删除捕获,.NET正则表达式有一个称为平衡组的构造。此构造的完整格式为(? 子表达式)

  • 首先,name2以前必须已捕获。
  • 然后子表达式必须匹配。
  • 如果存在name1,则name2捕获结束与子表达式匹配开始之间的子字符串被捕获到name1中。
  • 然后删除name2的最新捕获。(这意味着可以在子表达式中反向引用旧值。)
  • 匹配将提前到子表达式的末尾。

如果您知道name2正好捕获了一次,那么可以使用(?<-name2>)将其删除;如果不知道是否捕获了name2,则可以使用(?>(?<-name2>)?)或条件。如果您从那时起多次捕获name2,则会出现问题,这取决于您是否能够组织足够多的删除name2的重复。((?<-name2>)*不起作用,因为对于零长度匹配,*等同于。)

 类似资料:
  • 问题内容: 是否可以用来捕获任意一组可选参数? 例如,以下两个都应被接受为输入: 先验的 我不知道会指定哪些可选参数,但是会相应地处理它们。 问题答案: 这是一种黑客手段,但效果很好: 检查未添加的参数并添加它们 例如: 那么结果将是

  • 问题内容: 此问题与跨域资源共享(CORS)有关。 如果在发出CORS请求时出现错误,Chrome(以及AFAIK其他浏览器)会将错误记录到错误控制台。消息示例可能如下所示: XMLHttpRequest无法加载。原产地不被访问控制允许来源允许的。 我想知道是否有办法以编程方式获取此错误消息?我尝试将调用包装在try/catch中,也尝试添加事件处理程序。两者均未收到错误消息。 问题答案: 看到:

  • 我有这个代码: outlets是传递给方法的ArrayList;riverBasin是int(int[]riverBasin)的2D“矩阵”; 从ArrayList outlets中删除“项”会生成错误: 但我并不完全理解。然而,我怀疑我弄坏了迭代器。对的那么我如何删除ArrayList中不需要的元素呢。 提前感谢您的帮助, 里卡多

  • 我们的elasticsearch上有几个索引。它们来自FluentD,将发送日志插入docker容器。我们希望删除旧索引,不仅要根据索引名称删除超过特定天数的索引,还要根据日志字段应用不同的删除规则。 以下是日志示例: 在这种情况下,我们希望删除所有匹配早于7天的日志。 是否可以定义删除由此类字段值过滤的索引的Curator操作? 我们尝试了不同的过滤,但没有成功。我们成功执行的唯一操作是基于索引

  • 我在服务器中执行docker()清洁命令: 令我惊讶的是,这个命令删除了停止的容器。这就是问题所在,有些容器因为某种原因停止了,但我仍然想在未来使用它。现在它被删除了,有没有可能恢复错误删除的停止的容器?

  • 问题内容: 任何Throwable都可以被捕获 输出: 因此,如果在初始化块期间做不好的事情,我希望能够捕获ExceptionInInitializerError。但是,以下操作无效: 输出: 并且如果我更改代码以另外捕获ArrayIndexOutOfBoundsException 被捕获的是ArrayIndexOutOfBoundsException: 谁能告诉我为什么呢? 问题答案: 顾名思义