2016-04-15 31 views
5

mam ciąg jak na poniższymJak sprawić, by ten dziwny ciąg eksplodował w PHP?

DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string] 

Powyższy ciąg jest rodzajem sformatowane w grupach, które wygląda następująco:

A-B[C]-D-E-[F]-G-[H] 

Think jest to, że chciałbym przetwarzać niektóre z tych grupy i lubię sprawiać, że coś takiego eksploduje.

powiem jak, bo mam wypróbować ten kod:

$string = 'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]'; 
$parts = explode('-', $string); 
print_r($parts); 

i pojawia się następujący wynik:

Array 
(
    [0] => DAS 
    [1] => 1111[DR 
    [2] => Helpfull 
    [3] => R] 
    [4] => RUN 
    [5] => 
    [6] => [121668688374] 
    [7] => N 
    [8] => [+helpfull_+string] 
) 

, że nie jest to, czego potrzebuję.

Co potrzebne jest następujące wyjścia:

Array 
(
    [0] => DAS 
    [1] => 1111[DR-Helpfull-R] 
    [2] => RUN 
    [3] => 
    [4] => [121668688374] 
    [5] => N 
    [6] => [+helpfull_+string] 
) 

Czy ktoś mógłby sugerować, piękny i elegancki sposób, aby rozłożyć ten ciąg w sposób, jaki jest potrzebny?

o czym zapomniałem wspomnieć, to że ciąg może zawierać więcej lub mniej grup. Przykłady:

DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string] 
DAS-1111[DR-Helpfull-R]-RUN--[121668688374] 
DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart 

Aktualizuj 1

Jak wspomniano przez @axiac The preg_split może wykonać pracę. Ale czy możesz teraz pomóc w regex?

Muszę spróbować tego, ale wydaje się, że to nie jest prawidłowe:

(?!\]\-)\-

+1

To wygląda na zadanie dla [ 'preg_split()'] (http://php.net/manual/en/function.preg-split.php). – axiac

+0

Czy ciąg składa się ze stałych grup długości? Czy zatem pierwsza kolumna (DAS w twoim przykładzie) zawsze będzie pierwszymi trzema znakami? Czy drugie 18 znaków itp.? –

+0

@axiac Mmm Nie znałem tej funkcji. Mam zamiar spróbować wrócić :) –

Odpowiedz

5

Kod:

$str = 'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]'; 
$re = '/([^-[]*(?:\[[^\]]*\])?[^-]*)-?/'; 

$matches = array(); 
preg_match_all($re, $str, $matches); 
print_r($matches[1]); 

Jego wyjście:

Array 
(
    [0] => DAS 
    [1] => 1111[DR-Helpfull-R] 
    [2] => RUN 
    [3] => 
    [4] => [121668688374] 
    [5] => N 
    [6] => [+helpfull_+string] 
    [7] => 
) 

jest dodatkowa pusta wartość w pozycji 7 na wyjściu. Pojawia się z powodu kwantyfikatora powtórzeń zerowego lub jednego (?) umieszczonego na końcu regex. Kwantyfikator jest potrzebny, ponieważ bez niego ostatni element (o indeksie 6) nie jest dopasowany.

Możesz usunąć ? po ostatnim - i zapytać w ten sposób kreska (-) zawsze pasuje.W takim przypadku musisz dodać dodatkowy - do łańcucha wejściowego.

regex

(    # start of the 1st subpattern 
       # the captured value is returned in $matches[1] 
    [^-[]*  # match any character but '-' and '[', zero or more times 
    (?:   # start of a non-capturing subpattern 
    \[   # match an opening square bracket ('[') 
    [^\]]*  # match any character but ']', zero or more times 
    \]   # match a closing square bracket (']') 
)?   # end of the subpattern; it is optional (can appear 0 or 1 times) 
    [^-]*  # match any character but '-', zero or more times 
)    # end of the 1st subpattern 
-?    # match an optional dash ('-') 
2

Zamiast eksplozji należy spróbować dopasować następujący wzór:

(?:^|-)([^-\[]*(?:\[[^\]]+\])?) 

Here is an example:

$regex = '/(?:^|-)([^-\[]*(?:\[[^\]]+\])?)/'; 
$tests = array(
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]', 
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]', 
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart' 
); 
foreach ($tests as $test) { 
    preg_match_all($regex, $test, $result); 
    print_r($result[1]); 
} 

Wyjście:

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string] 
Array 
(
    [0] => DAS 
    [1] => 1111[DR-Helpfull-R] 
    [2] => RUN 
    [3] => 
    [4] => [121668688374] 
    [5] => N 
    [6] => [+helpfull_+string] 
) 

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374] 
Array 
(
    [0] => DAS 
    [1] => 1111[DR-Helpfull-R] 
    [2] => RUN 
    [3] => 
    [4] => [121668688374] 
) 

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart 
Array 
(
    [0] => DAS 
    [1] => 1111[DR-Helpfull-R] 
    [2] => RUN 
    [3] => 
    [4] => [121668688374] 
    [5] => N 
    [6] => [+helpfull_+string] 
    [7] => anotherPart 
) 
+0

Użyłem twojego wzorca używając zarówno 'preg_match' i' preg_split' ale żaden nie działa: (W każdym razie, dziękuję za próbę :) –

+1

@MerianosNikos mój PHP jest nieco zardzewiały. Poprawię odpowiedź po kolejnych testach. –

+0

sprawdziłem na mojej maszynie .. działa idealnie ... https://3v4l.org/aNnoU –

1

Przypadek ten jest idealny dla metody (*SKIP)(*FAIL). Chcesz podzielić strunę na łączniki, o ile nie znajdują się w nawiasach kwadratowych.

Łatwo. Wystarczy dyskwalifikują te myślniki jako ograniczniki tak:

Wzór: ~\[[^]]+\](*SKIP)(*FAIL)|-~ (Pattern Demo)

Kod: (Demo)

$strings=['DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]', 
      'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]', 
      'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart']; 

foreach($strings as $string){ 
    var_export(preg_split('~\[[^]]+\](*SKIP)(*FAIL)|-~',$string)); 
    echo "\n\n"; 
} 

wyjściowa:

array (
    0 => 'DAS', 
    1 => '1111[DR-Helpfull-R]', 
    2 => 'RUN', 
    3 => '', 
    4 => '[121668688374]', 
    5 => 'N', 
    6 => '[+helpfull_+string]', 
) 

array (
    0 => 'DAS', 
    1 => '1111[DR-Helpfull-R]', 
    2 => 'RUN', 
    3 => '', 
    4 => '[121668688374]', 
) 

array (
    0 => 'DAS', 
    1 => '1111[DR-Helpfull-R]', 
    2 => 'RUN', 
    3 => '', 
    4 => '[121668688374]', 
    5 => 'N', 
    6 => '[+helpfull_+string]', 
    7 => 'anotherPart', 
)