嵌套括号前有文本的递归正则表达式


Recursive regex with text before nested parenthesis

我有以下文本

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

我需要从文本中获取带有regex的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)"
}

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

如何在第一个打开的(之前递归地匹配并返回一个嵌套的括号和单词something,如果可能的话,会发生什么,那么单词something之前可能有空白,也可能没有空白,例如

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

(?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)[^()]*)*+'))
[^() ]*('((?:[^()]|(?1))*'))

您需要使用?1(?1) recurses the 1st subpattern。请参阅演示。

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

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

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

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