2016-04-15 11 views
5

Ho una stringa simile alla seguenteCome far esplodere questa strana stringa in PHP?

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

La stringa di cui sopra è una sorta di formattata in gruppi che è simile al seguente:

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

Il pensare è che mi piace di elaborare alcuni di quelli gruppi, e mi piace fare qualcosa come esplodere.

dire come, perché ho provate questo codice:

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

e ottengo il seguente risultato:

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

che non è quello che mi serve.

cosa ho bisogno è il seguente output:

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

Qualcuno può suggerire un modo piacevole ed elegante per esplodere questa stringa nel modo in cui ho bisogno?

quello che ho dimenticato di menzionare, è che la stringa può avere più o meno gruppi. Esempi:

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 

Update 1

Come accennato dal @axiac, il preg_split può fare il lavoro. Ma puoi aiutarmi per favore con la regex adesso?

devo provare questo, ma sembra che non è corretto:

(?!\]\-)\-

+1

Sembra un lavoro per [ 'preg_split()'] (http://php.net/manual/en/function.preg-split.php). – axiac

+0

La stringa è composta da gruppi di lunghezza fissa? Quindi, la prima colonna (DAS nel tuo esempio) sarà sempre i primi tre caratteri? I secondi 18 caratteri ecc.? –

+0

@axiac Mmm non sapevo questa funzione. Sto cercando di tornare di nuovo :) –

risposta

5

Il codice:

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

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

sua uscita:

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

C'è un valore vuoto aggiuntivo nella posizione 7 nell'output. Appare a causa del quantificatore di ripetizioni zero-or-one (?) collocato alla fine dello regex. Il quantificatore è necessario perché senza di esso l'ultimo pezzo (all'indice 6) non corrisponde.

È possibile rimuovere ? dopo l'ultimo - e chiedere in questo modo che il trattino (-) corrisponda sempre.In questo caso è necessario aggiungere un ulteriore - alla stringa di input.

La 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

invece di esplodere si dovrebbe cercare di abbinare il seguente schema:

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

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]); 
} 

Uscita:

// 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

Ho usato il tuo pattern usando sia 'preg_match' che' preg_split' ma nessuno funziona: (.) Comunque, grazie per il tuo tentativo :) –

+1

@MerianosNikos il mio PHP è un po 'arrugginito. Aggiornerò la risposta dopo un po 'di test. –

+0

controllato sulla mia macchina .. perfettamente funzionante ... https://3v4l.org/aNnoU –

1

Questo caso è ideale per il metodo (*SKIP)(*FAIL). Vuoi dividere la stringa sui trattini, purché non siano all'interno di parentesi quadre.

Facile. Proprio squalificare questi trattini come delimitatori in questo modo:

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

Codice: (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"; 
} 

uscita:

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', 
) 
Problemi correlati