2

縦棒で弦を爆発させようとしています。それは簡単な部分です。ただし、括弧で囲まれた部分文字列に分割が影響することは望ましくありません。つまり、次のような文字列が必要です。

Hello (sir|maam).|Hi there!

爆発する:

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

通常の分解機能を使用することで、括弧で囲まれたバーを無視するように指示する方法はないと思います。しかし、私にはいくつかのアイデアがあります。

(文字列を通常どおりに展開し、配列をループして、を含む文字列とを含む終了文字列の間のすべてをマージすることで、これを行うことができることを私は知っています)。しかし、これを実現するためのよりエレガントな方法があるべきだと私は感じています。

私は正しいですか?これらの制限を考慮して、文字列を配列に分割するコード集約型の手段はありますか?

4

2 に答える 2

3

括弧がバランスが取れていてネストされないことを保証でき(つまり、'Oops(!'またはが存在しない場合'(nested stuff (like this)|oops)')、||空の文字列として一致させたい括弧の外側が存在しない場合は、これが役立つはずです。 :

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

[(またはではない文字)、またはa|であり、 (を含む)ではないものを囲む]と、可能な限り何度も(ただし少なくとも1回は)一致します。短いバージョン:括弧ではなく、括弧の間に一致の一部を作成します。(())||

もう1つの可能性は、少しわかりにくいです。

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

先読みアサーションを使用して、間にがない場合に|後に続くものを失格にします。まだparensについては少し寛容ではありませんが、2つの間の空の文字列と一致します。)(|

于 2012-08-12T02:14:54.957 に答える
1

誰かが正規表現ベースのソリューションを作成するまでは、これは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 に答える