2017-12-04 2 views
0

文字列にカンマまたは区切りの色名があります。文字:分割文字列をカンマで区切ります。例外はありません。

$s = 'Blue | Red (light, dark) | Green, Yellow, Brown'; 

私は配列に変換する必要があります。

$colors = preg_split('![\|,]!', $s); 

しかし、結果は次のとおりです。

Array 
(
    [0] => Blue 
    [1] => Red (light 
    [2] => dark) 
    [3] => Green 
    [4] => Yellow 
    [5] => Brown 
) 

これは、カンマで "光、闇" の文字列を分割します。私はカッコ内ではなくコンマで分割したいと思います。希望の結果:

Array 
(
    [0] => Blue 
    [1] => Red (light, dark) 
    [2] => Green 
    [3] => Yellow 
    [4] => Brown 
) 

どうすれば解決できますか?

答えて

1

あなたは、交換する前に、入力文字列のparenthesed部分をマスクする必要があります。

$s = 'Blue | Red (light, dark) | Green, Yellow, Brown'; 

// Mask the parenthesed sections. 
// Replace the ',' character with a unique string which you can guarantee will not occur (here: '===') 
$sr = 
    preg_replace_callback(
     '!\([^\)]+\)!' 
    , function ($p_hit) { return str_replace(',', '===', $p_hit[0]); } 
    , $s 
    ); 

// original split 
$colors = preg_split('![\|,]!', $sr); 

// undo masking 
$colors = array_map (
    function ($elem) { return str_replace('===', ',', $elem); } 
    , $colors 
); 

// Print result 
print_r ($colors); 

出力:

Array 
(
[0] => Blue 
[1] => Red (light, dark) 
[2] => Green 
[3] => Yellow 
[4] => Brown 
) 

このソリューションは、ネストされたかっこを含むソース文字列では機能しません。

2
$str = 'Blue | Red (light, dark) | Green, Yellow, Brown (light | bright)'; 
$res = preg_split('/ 
        (   # group 1 
         [^|,]* # 0 or more not pipe or comma 
         \(  # open parenthesis 
         [^()]* # 0 or more not parenthesis 
         \)  # close parenthesis 
        )   # end group 1 
        |   # OR 
        [|,]  # a pipe or a comma 
        /x', 
        $str, -1, 
        PREG_SPLIT_NO_EMPTY 
        | PREG_SPLIT_DELIM_CAPTURE); 
print_r($res); 

出力:

Array 
(
    [0] => Blue 
    [1] => Red (light, dark) 
    [2] => 
    [3] => Green 
    [4] => Yellow 
    [5] => Brown (light | bright) 
) 
0

括弧内の区切り文字は、(*SKIP)(*FAIL)で除外する必要があります。また、デリミタの前後にゼロ個以上のスペースを追加して、出力値を整えるようにしました。

コード:(Demo

$s = 'Blue | Red (light, dark) | Green, Yellow, Brown'; 
$colors = preg_split('/\([^)]+(*SKIP)(*FAIL)|\s*[,|]\s*/',$s); 
var_export($colors); 

echo "\n"; 

$str = 'Blue | Red (light, dark) | Green, Yellow, Brown (light | bright)'; 
$colors = preg_split('/\([^)]+(*SKIP)(*FAIL)|\s*[,|]\s*/',$str); 
var_export($colors); 

出力:

array (
    0 => 'Blue', 
    1 => 'Red (light, dark)', 
    2 => 'Green', 
    3 => 'Yellow', 
    4 => 'Brown', 
) 
array (
    0 => 'Blue', 
    1 => 'Red (light, dark)', 
    2 => 'Green', 
    3 => 'Yellow', 
    4 => 'Brown (light | bright)', 
) 

arguementのために、あなたは自分のサンプルの入力文字列でこれを使用することもできます。

var_export(preg_match_all('/[a-z]+(?: \([^)]+\))?/i',$str,$out)?$out[0]:'fail'); 

この大文字無感性に色にマッチし、括弧で囲まれた式の後にオプションで含まれます。同じ出力。

+0

@LayAndrásトリムされた文字列を出力する効率的で洗練されたソリューションを投稿しました。私はこれがあなたのプロジェクトで使うべき方法だと感じています。私の答えについてご質問がありますか? – mickmackusa

関連する問題