2

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

Hello (sir|maam).|Hi there!

爆炸成:

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

通过使用正常的爆炸功能,我不相信有办法告诉它忽略括号包围的那个栏。不过,我有一些想法。

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

我对吗?考虑到这些限制,是否有一种代码密集度较低的方法可以将字符串拆分为数组?

4

2 回答 2

3

如果您可以保证括号是平衡的并且永远不会嵌套(也就是说,如果永远不会有 a'Oops(!'或 a '(nested stuff (like this)|oops)'),并且永远不会有||括号之外的括号可以匹配为空字符串,那么这应该会有所帮助:

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

它将尽可能多次(但至少一次)匹配 [要么(一个不是 a|或的字符(),要么是 a()包含任何不是 a 的内容)(包括)]。|简短版本:它将|在括号之间作为匹配的一部分,而不是分隔符。

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

$parts = preg_split('/\|(?![^(]*\))/', $your_string);

如果中间没有 a ,则使用前瞻断言来取消任何|后面跟着 a 的资格。仍然对parens有点无情,但它会匹配两个s之间的空字符串。)(|

于 2012-08-12T02:14:54.957 回答
1

直到有人编写了一个基于正则表达式的解决方案,我怀疑这可以通过一次通过,这应该可以工作。它是将需求直接转换为代码。

<?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));
于 2012-08-12T02:05:46.810 回答