爆炸字符串除了用括号括起来的地方?

时间:2012-08-12 00:51:07

标签: php

我试图通过竖线爆炸一个字符串。这很容易。但是,我不希望拆分影响括号括起来的子串。这意味着我需要一个字符串,如:

Hello (sir|maam).|Hi there!

爆炸成:

Array
(
    [0] => Hello (sir|maam).
    [1] => Hi there!
)

通过使用普通爆炸功能,我不相信有一种方法可以告诉它忽略圆括号所包围的条形。但是,我有一些想法。

我知道可以通过正常爆炸字符串,然后循环遍历数组并将包含(的字符串之间的所有内容合并到包含)的结束字符串来实现此目的。但是,我觉得应该有更优雅的方式实现这一目标。

我是对的吗?在给定这些限制的情况下,是否存在代码密集度较低的将字符串拆分为数组的方法?

2 个答案:

答案 0 :(得分:3)

如果你能保证括号是平衡的而且从不嵌套(也就是说,如果永远不会有'Oops(!''(nested stuff (like this)|oops)'),那么永远不会有||在你想要匹配为空字符串的括号之外,这应该有所帮助:

preg_match_all('/(?:[^(|]|\([^)]*\))+/', $your_string, $matches);
$parts = $matches[0];

它会匹配[一个不是|(的字符),或一个()包围任何不是{{1}的内容}(包括))],尽可能多次(但至少一次)。简短版本:它会在匹配的括号之间设置|,而不是分隔符。

另一种可能性,即稍微不那么神秘:

|

如果中间没有$parts = preg_split('/\|(?![^(]*\))/', $your_string); ,则使用先行断言来取消|之后)所有{{}}}的资格。 parens仍然有点无情,但它会匹配两个(之间的空字符串。

答案 1 :(得分:0)

直到有人写一个基于正则表达式的解决方案,我怀疑单次传递是否可行,这应该有效。它是对代码的直接需求翻译。

<?php
function my_explode($str)
{
    $ret = array(); $in_parenths = 0; $pos = 0;
    for($i=0;$i<strlen($str);$i++)
    {
        $c = $str[$i];

        if($c == '|' && !$in_parenths) {
            $ret[] = substr($str, $pos, $i-$pos);
            $pos = $i+1;
        }
        elseif($c == '(') $in_parenths++;
        elseif($c == ')') $in_parenths--;
    }
    if($pos > 0) $ret[] = substr($str, $pos);

    return $ret;
}

$str = "My|Hello (sir|maam).|Hi there!";
var_dump(my_explode($str));