【问题标题】:Explode string except where surrounded by parentheses?爆炸字符串除了被括号包围的地方吗?
【发布时间】:2012-08-12 00:51:07
【问题描述】:

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

Hello (sir|maam).|Hi there!

爆炸成:

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

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

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

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

【问题讨论】:

标签: php


【解决方案1】:

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

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

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

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

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

如果没有( ,则使用前瞻断言来取消任何| 后跟) 的资格。对parens 还是有点不宽容,但它会匹配两个|s 之间的空字符串。

【讨论】:

    【解决方案2】:

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

    <?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));
    

    【讨论】:

      猜你喜欢
      • 2019-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多