2017-12-04 3 views
0

쉼표 또는 쉼표로 구분 된 색상 이름의 문자열이 있습니다. 문자 :쉼표로 쉼표로 구분 된 문자열

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

그러나 결과는 다음과 같습니다 :

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

나는 배열로 변환 할 필요가

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

:

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

출력 : 당신은 교체하기 전에 입력 문자열의 parenthesed 부분을 마스크 할 필요가

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

괄호 안에있는 구분 기호는 (*SKIP)(*FAIL) 일 경우에만 자격을 박탈해야합니다. 또한 출력 값이 잘 리도록 구분 기호 앞뒤에 0 개 이상의 공백을 추가했습니다.

코드 : (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)', 
) 

아규먼트의 위해, 당신은 샘플 입력 문자열에서이를 사용할 수 있습니다

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

이 대소 색상과 무관하게 일치하고 선택적으로 후행 괄호 식을 선택적으로 포함합니다. 같은 출력.

+0

@ LayAndrás 트리밍 된 문자열을 출력하는 효율적/세련된 솔루션을 게시했습니다. 나는 이것이 당신이 당신의 프로젝트에서 사용해야하는 방법이라고 생각합니다. 내 대답에 대해 질문이 있으십니까? – mickmackusa