PHP preg_split,只保留整个正则表达式作为分隔符,忽略括号内的内容


PHP preg_split and keeping only the entire regex as a delimiter, ignoring inside parentheses

我试图在字符串上使用更复杂的regex和preg_split来获得所有匹配项的数组并保留分隔符。通常情况下,这很简单,但尝试使用PREG_SPLIT_DELIM_CAPTURE并在我的正则表达式中使用多组括号是很困难的。我将详细说明:

我想解析一行中的一个IP地址,并将整行分解成一个数组,这样我就可以只对IP进行特定的处理,但我想最终显示整行(我对IP应用格式,然后重新组装并显示字符串)。我的正则表达式是这样的(它检查看起来像IP的东西,但不检查有效性,我现在不在乎):

((('d{1,3})'.){3}('d{1,3}))

现在,我暂时的代码是:$ipv4regex="/(((''d{1,3}).){3}(''d{1,3}))/";

if (contains_ipv4($line)){
    $pieces = preg_split($ipv4regex, $line, 0, PREG_SPLIT_DELIM_CAPTURE);
    print "<pre>";
    print_r($pieces);
    print "</pre>";
}
function contains_ipv4($val){
    return (preg_match($ipv4regex, $val));
}

下面是我的输出示例(IP地址已更改,但仍然相关):

Array
(
    [0] => show arp results from 
    [1] => 10.10.15.120
    [2] => 15.
    [3] => 15
    [4] => 120
    [5] => 
)

我如何更改它以使输出如下:

(
    [0] => show arp results from 
    [1] => 10.10.15.120
    [2] => 
)

本质上,我只想捕获PREG_SPLIT_DELIM_capture正则表达式中最外层的括号,而不是内部的括号。我知道我可以针对这种特殊情况更改我的正则表达式,但我有一个"合适的"IPv6正则表达式,里面有很多括号,我担心只在外面用一组括号重写几乎是不可能的。有人能帮我吗?我会非常感激。或者,如果我错过了一种完全不同的方式,请随时为我指明方向。

您可以通过在括号后面添加?:来取消激活括号捕获,例如:

((?:(?:'d{1,3})'.){3}(?:'d{1,3}))

我设法减少了该方法的总体混乱,并将其改进为只使用几行代码:

if (preg_match($ipv4regex, $line)){
    $line = preg_replace_callback($ipv4regex, 'add_ipv4_p', $line);
}

稍后我会打印这一行,但这个简单的部分就是我检查正则表达式所需要的add_ipv4_p方法是我用来对传递给它的数组的第一个元素应用格式的方法。很简单。我只需重新使用这个片段并更改正则表达式和格式化方法,就可以为代码添加更多的格式化选项。