我有以下文本
$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