Php 如何获取最后一个嵌套的“(`和`)`之间的字符串,但如果没有字符串,则获取该嵌套的直接父级“()”之间的字符串?

Php 如何获取最后一个嵌套的“(`和`)`之间的字符串,但如果没有字符串,则获取该嵌套的直接父级“()”之间的字符串?,php,regex,Php,Regex,假设我有这个字符串: date_format(from_days(datediff(now(),api.dob)),'%y')+0 我想检查嵌套最多的()的内容,在上面的示例中是now(),但如果其中没有字符串,则获取下一个api.dob。如果嵌套的内容为空,则外部()的顺序相同。 如何使用php实现这一点? 我也问过同样的问题 但是如果嵌套的一个内容是空的,那么应该按顺序获取下一个内容。我建议使用类似的条件正则表达式 \w+\((?<in>[^()]+)?\)(?(in)|,\K

假设我有这个字符串:

date_format(from_days(datediff(now(),api.dob)),'%y')+0
我想检查嵌套最多的
()
的内容,在上面的示例中是
now()
,但如果其中没有字符串,则获取下一个
api.dob
。如果嵌套的内容为空,则外部
()
的顺序相同。 如何使用php实现这一点? 我也问过同样的问题
但是如果嵌套的一个内容是空的,那么应该按顺序获取下一个内容。

我建议使用类似的条件正则表达式

\w+\((?<in>[^()]+)?\)(?(in)|,\K[^,()]+)
更新

由于您需要的子字符串可能位于实际设置匹配选择条件的子字符串之前,因此您需要实际捕获您感兴趣的所有部分,并检查匹配的组

我建议采取以下变化:

(?:(?<res1>\w+(?:\.\w+)+)[^()]*\()?\b(?<res2>\w+\((?<in>[^()]+)?\))(?(in)|,(?<res3>\w+(?:\.\w+)+))?
(?:(?:\。\w+)[^()]*\())(?:(?[^())+)(?(in)|,(?\w+(?:\。\w+)?

:

$re='/(?:(?:(?:\.\w+)[^()]*\())(?(?[^())+)(?(in)|,(?\w+(?:\.\w+)))/;
$strs=array('date\'格式(from\'days(datediff(now(),api.dob)),\'%y\'),
“日期”格式(从日期(datediff(现在(\'here\',api.dob)),\'%y\'),
'如果(awe.date\u to>=date\u sub(now(),间隔3年),'是','否')';
foreach($str作为$str){
if(预匹配($re,$str,$match)){
如果(!empty($match[“res3”])){
echo$match[“res3”].PHP_EOL;
}
如果(!empty($match[“res1”]),则为else{
echo$match[“res1”].PHP_EOL;
}
else echo$match[“res2”].PHP_EOL;
};
}

@shA.t它与它们都匹配,如果
now()
中存在任何东西,它也会返回
api.dob
,它不应该这样做,在这种情况下,它应该只返回
now()
的内容,但是如果
now()
为空,因此应返回
api.dob
@shA.t,但您的上一个字符串不处理那些只有一个
()
,且未嵌套的字符串。条件字符串呢?If“res“是成功的,接受它。如果不是,则获取整个匹配值。好的,要获取组0中的所有匹配项,您可以在条件-@WiktorStribizew中使用
\K
。”谢谢,它是working@WiktoStribizew另一个问题。我们如何检查
res
组匹配字符串是否是与
(点)连接的单词假设这个字符串:
if(awe.date\u to>=date\u sub(now(),间隔3年),'yes','no')“
res
组为
间隔3年
,因为这不是与
连接的,所以获取
awe.date\u to
我们如何在其他部分签入应与
连接的匹配字符串,如果不是,则检查父
()
content并只获取一次点连接字符串。该
awe.date\u to
位于
now()
之前。您需要捕获该部分以及所有其他部分,然后对正则表达式匹配的内容执行更深入的检查。请参阅。
(?:(?<res1>\w+(?:\.\w+)+)[^()]*\()?\b(?<res2>\w+\((?<in>[^()]+)?\))(?(in)|,(?<res3>\w+(?:\.\w+)+))?
$re = '/(?:(?<res1>\w+(?:\.\w+)+)[^()]*\()?\b(?<res2>\w+\((?<in>[^()]+)?\))(?(in)|,(?<res3>\w+(?:\.\w+)+))?/';
$strs = array('date_format(from_days(datediff(now(),api.dob)),\'%y\')',
'date_format(from_days(datediff(now(\'here\'),api.dob)),\'%y\')',
'if(awe.date_to >= date_sub(now(),interval 3 year),\'yes\',\'no\')"');

foreach ($strs as $str) {
    if (preg_match($re, $str, $match)) {
        if (!empty($match["res3"])) {
            echo $match["res3"] . PHP_EOL;
        }
        else if (!empty($match["res1"])) {
            echo $match["res1"] . PHP_EOL;
        }
        else echo $match["res2"] . PHP_EOL;
    };
}