【问题标题】:Recursive regex with text before nested parenthesis嵌套括号前带有文本的递归正则表达式
【发布时间】:2015-10-05 17:16:50
【问题描述】:

我有以下文字

$text = 'This is a test to see if something(try_(this(once))) works';

我需要从文本中获取带有正则表达式的something(try_(this(once)))。我有以下问题

  • 我的嵌套不会保持不变,我的文本可以是

    • something(try_(this(once)))
    • something(try_this(once))
    • something(try_thisonce)

我已经尝试了在整个网站上找到的许多正则表达式,但无法使其正常工作。这是我最近的一次

示例 1:

$text = 'This is a test to see if something(try_(this(once))) works';
$output = preg_match_all('/(\(([^()]|(?R))*\))/', $text, $out);
?><pre><?php var_dump($out[0]); ?></pre><?php   

这个输出

array(1) {
  [0]=>
  string(18) "(try_(this(once)))"
}

无论我在哪里添加单词something例如'/something(\(([^()]|(?R))*\))/''/(\something(([^()]|(?R))*\))/'),我都会得到一个空数组或NULL

示例 2

$text2 = 'This is a test to see if something(try_(this(once))) works';
$output2 = preg_match_all('/something\((.*?)\)/', $text2, $out2);
?><pre><?php var_dump($out2[0]); ?></pre><?php  

有了这段代码,我确实得到了something这个词,

array(1) {
  [0]=>
  string(25) "something(try_(this(once)"
}

但随后表达式停止并在第一次关闭 ) 后返回,这是预期的,因为这不是递归表达式

如何在第一个开头 ( 之前递归匹配并返回带有单词 something 的嵌套括号,如果可能的话,那么在单词 something 之前可能会有也可能没有空格,因为例子

  • something(try_(this(once)))
  • something (try_(this(once)))

【问题讨论】:

  • 你为什么不能这样做? regex101.com/r/jW9iW0/1
  • @dustmouse 它同样适用于something(try_(this(once))),但something (try_(this(once))) 什么也不返回。任何想法如何在可能发生或可能不发生的情况下匹配空格,请将其发布为答案,以便我给您一些信用
  • 好的,我发布了一个可以处理空格的答案。

标签: php regex recursion


【解决方案1】:

(?R) 不是获得能够处理平衡事物的模式的神奇咒语(例如括号)。 (?R)(?0) 是一回事,它是“捕获组零”的别名,也就是整个模式。

同样,您可以使用(?1)(?2) 等作为组 1、2 等中子模式的别名。

顺便说一句,请注意除了 (?0)(?R) 显然总是在它们的子模式中,因为它是整个模式,(?1)(?2) 只有在它们处于它们各自的组,并且只能用于不重写模式的一部分。

something\((?:[^()]|(?R))*\) 不起作用,因为它强制每个嵌套(或不)的左括号在您的字符串中以 something 开头。

结论,这里不能使用(?R),需要创建一个捕获组只处理嵌套括号:

(\((?:[^()]|(?1))*\))

可以用更有效的方式编写:

(\([^()]*(?:(?1)[^()]*)*+\))

要完成,您只需添加不再包含在递归中的something

something(\([^()]*(?:(?1)[^()]*)*+\))

请注意,如果something 是具有不确定数量的捕获组的子模式,则使用这样的相对引用来引用最后打开的捕获组会更方便:

som(eth)ing(\([^()]*(?:(?-1)[^()]*)*+\))

【讨论】:

    【解决方案2】:
    [^() ]*(\((?:[^()]|(?1))*\))
    

    您需要使用?1.(?1) recurses the 1st subpattern。查看演示。

    https://regex101.com/r/cJ6zQ3/4

    【讨论】:

    • 很好,它适用于something(try_(this(once))),但something (try_(this(once))) 什么也不返回。任何想法如何在事件发生时匹配空格
    【解决方案3】:

    这是匹配所需文本并处理嵌套括号的一种非常直接的方式:

    something\s*\(.*?\)+
    

    https://regex101.com/r/cN6nQ9/1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 2010-12-26
      • 2013-06-14
      相关资源
      最近更新 更多