当前位置: 首页 > 面试题库 >

正则表达式中的递归模式

邵浩大
2023-03-14
问题内容

这与正则表达式匹配外括号非常相关,但是,我特别想知道该
正则表达式的递归模式
如何或是否可行?
我尚未找到使用此策略的python示例,因此认为这应该是一个有用的问题!

我已经看到
了一些
索赔
是递归的模式可以用来匹配平衡括号,但使用Python的没有例子正则表达式包(注:重
支持递归模式,你需要使用正则表达式)。

一种说法是语法位于b(?:m|(?R))*e

b是开始构造的东西,m是可能在构造中间发生的东西,是可能在构造e结束时发生的东西

我想在下面提取 括号的匹配项:

"{1, {2, 3}} {4, 5}"
["1, {2, 3}", "4, 5"]  # desired

请注意,这对于 内部 括号很容易做到:

re.findall(r"{([^{}]*)}", "{1, {2, 3}} {4, 5}")
['2, 3', '4, 5']

(在我的示例中,我正在使用finditer(在match对象上),请参见
此处。)

因此,我希望以下内容或某些变体能够起作用:

regex.findall(r"{(:[^{}]*|?R)}", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:[^{}]*|?R)})", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:.*|(?R))*})", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:.*)|(?R)*})", "{1, {2, 3}} {4, 5}")
regex.findall(r"({(:[^{}])|(?R)})", "{1, {2, 3}} {4, 5}")

但我为[]或感到沮丧error: too much backtracking

是否可以使用正则表达式的递归为外部括号提取匹配对象?

显然,我冒着被以下人员击落的风险:

  • 不要用正则表达式解析html
  • 用pyparse做到这一点
  • 编写适当的词法分析器和解析器,例如使用ply

我想强调一下这是关于 如何使用递归模式的
(如果我的理解是正确的,那么它将使我们脱离常规语言的分析范围,因此实际上可能!)。如果可以做到,那应该是一个更清洁的解决方案。


问题答案:

模式是:

{((?>[^{}]+|(?R))*)}

您可以看到此示例适用于您:

regex.findall("{((?>[^{}]+|(?R))*)}", "{1, {2, 3}} {4, 5}")
# ['1, {2, 3}', '4, 5']

说明:

m部分需要排除括号。如果您希望同时允许一个量词[^{}]并重复该基团而没有催化回溯问题,则需要使用原子基团。更明确地说,如果缺少最后一个大括号,则此正则表达式引擎将按原子组而不是逐个字符地回溯原子组。为了说明这一点,您可以使量词具有以下所有格:({((?>[^{}]+|(?R))*+)}{((?:[^{}]+|(?R))*+)}由于原子团不再有用)。

该原子团(?>....)和所有格量词?+*+++是相同的特征的两侧。此功能禁止正则表达式引擎在成为“原子”的字符组内回溯
(某些内容您不能分割成较小的部分)

基本示例是以下两种始终失败的模式aaaaaaaaaab

(?>a+)ab
a++ab

那是:

regex.match("a++ab", "aaaaaaaaaab")
regex.match("(?>a+)ab", "aaaaaaaaaab")

当您使用(?:a+)a+regex引擎时(默认情况下)记录(预先记录)所有字符的所有回溯位置。但是,当您使用原子组或所有格量词时,将不再记录这些回溯位置(组开始时除外)。因此,当发生回溯机制时,无法返回最后的“
a”字符。只有整个小组都可以退还。

[编辑]:如果您使用“展开”子模式来描述方括号之间的内容,则可以用更有效的方式编写模式:

{([^{}]*+(?:(?R)[^{}]*)*+)}


 类似资料:
  • 我希望有一个regex来匹配以开头的所有行,后面跟着以开头的任意数量的行。理想情况下,我希望将带有的每一行放在一个组中。 以下是我希望得到的结果: (为了缩短起见,我用了[...]。) 它实际上给了我这个: 我希望我已经说得够清楚了,你能帮我解决这个问题。请不要犹豫,询问更多的细节。

  • 我有一个这样的字符串: 我需要处理这样上面的代码就变成了 我需要一直这样做直到我 我的模式字符串将匹配整个内容。不是。 Java代码:

  • 问题内容: 该字符串可以类似于以下之一: 我想匹配不限数量的“ a(x,y)”。如何使用Regex做到这一点?这是我所拥有的: 它仅匹配“ a(x,y)”的两个递归。 问题答案: Java的标准正则表达式库不支持递归,因此您无法将此类通用嵌套结构与之匹配。 但是在确实支持递归的版本(Perl,PCRE,.NET等)中,您可以使用以下表达式:

  • 字符串可以类似于以下内容之一: 我想匹配无限数量的“a(x,y)”。我如何使用正则表达式来实现这一点?以下是我所拥有的: 它只匹配"a(x, y)"的两个递归。

  • 我需要编写一个具有以下规则的正则表达式: null null 这些示例无效: > 12--11(因为它包含两个连字符) 1-2345(因为它包含5号) <>是字符出现在最后一个位置,那么在字符之前必须有一个数字not hypen。 即11-A(必须不及格)11-1A(必须及格)

  • 我是正则表达式的初学者,并尝试搜索特定的数字模式。以下数据以 XML 格式嵌入。 要求是提取数据(最里面的列表)。在这个例子中,数据从24779开始到24760。注意:每次数据可能不是从“24”开始。因此,我计划通过以下逻辑提取:如果标签名(在本例中:DUT_1_PC)具有非零的有效数据,并且有效数据的计数大于100,用逗号分隔,则提取该列表及其标签名(DUT_1_PC)。 我无法提取所需的数据。