在嵌套括号之前使用文本的递归正则表达式

时间:2015-10-05 17:16:50

标签: php regex recursion

我有以下文字

$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 < / p>

示例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之前递归匹配并返回带有单词(的嵌套括号,如果可能,会发生什么,然后在单词{之前可能有也可能不会有空格{1}},例如

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

3 个答案:

答案 0 :(得分:3)

uint4 result = *(local uint4*)buffer;

您需要使用[^() ]*(\((?:[^()]|(?1))*\)) ?1。请参阅演示。

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

答案 1 :(得分:3)

(?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)

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

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

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