Php più delimitatori in esplodono


146

Ho un problema, ho un array di stringhe e voglio esplodere in un delimitatore diverso. Per esempio

$example = 'Appel @ Ratte';
$example2 = 'apple vs ratte'

e ho bisogno di un array che esploda in @ o vs.

Ho già scritto una soluzione, ma se tutti hanno una soluzione migliore, si prega di pubblicare qui.

private function multiExplode($delimiters,$string) {
    $ary = explode($delimiters[0],$string);
    array_shift($delimiters);
    if($delimiters != NULL) {
        if(count($ary) <2)                      
            $ary = $this->multiExplode($delimiters, $string);
    }
    return  $ary;
}

Non ho mai visto una domanda con persone che
davano

Risposte:


290

che dire di usare

$ output = preg_split ("/ (@ | vs) /", $ input);

Sorprendente. mi chiedo come questo si contrapponga explode()a singoli argomenti
Ascherer,

6
Non importa, se si desidera creare un sistema di grandi dimensioni con l'analisi delle stringhe rigide, il modo più efficace è il proprio parser. Altrimenti non ha molto effetto sulla velocità del sistema, ma preferisci usare il modo più semplice per te (per essere efficace in termini di denaro)
SergeS

9
Nota che alcuni personaggi devono essere salvati per funzionare (come /, ?). Ad esempio: preg_split("/(\/|\?|=)/", $foo);.
Kenorb,

preg_split restituisce un array indicizzato. È possibile tornare associativo? Ad esempio $str='/x/1/2/3/4/5/y/100/200/z/777'; preg_split("/(x|y|z|)/", $str); e per vederearray('x'=>'1/2/3/4/5', 'y'=>'100/200', 'z'=>'777')
LINKeRxUA,

2
Ho scoperto di avere degli spazi tra il / (e ) /impedito a preg_split di funzionare. Ho dovuto rimuovere gli spazi e poi ha funzionato come previsto (usando PHP 7)
Boardy

69

Puoi prendere la prima stringa, sostituire tutto @con l' vsutilizzo str_replace, quindi esplodere vso viceversa.


1
Soluzione semplice, ha finito per usarlo per il codice Json per sostituire "}}" con "|". Sporco ma efficiente :)!
Baldráni,

5
che genio: D
Deadpool il

questo non funzionerà correttamente quando un delimitatore è un superset dell'altro (es. (@|@!)case)

2
@vaxquis Sì. str_replace ('@!', '@', $ str); Assicurati di iniziare con il delimitatore più unico.
John Ballinger,

@JohnBallinger No, non hai - hai proposto un'altra soluzione, che mostra chiaramente che la soluzione originale non funzionerà correttamente e che la tua idea è difettosa. Immagina di non sapere quale sia il superset di un altro. Dovresti creare un'altra riga di codice per verificarlo ecc. Mentre odio le regex in generale, questo è un caso in cui è la soluzione migliore in termini di manutenibilità e semplicità.

47
function multiexplode ($delimiters,$string) {

    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
}

$text = "here is a sample: this text, and this will be exploded. this also | this one too :)";


$exploded = multiexplode(array(",",".","|",":"),$text);

print_r($exploded);

//And output will be like this:
// Array
// (
//    [0] => here is a sample
//    [1] =>  this text
//    [2] =>  and this will be exploded
//    [3] =>  this also 
//    [4] =>  this one too 
//    [5] => )
// )

Fonte: php @ metehanarslan su php.net


14

Che ne dici di usare strtr()per sostituire tutti gli altri delimitatori con il primo?

private function multiExplode($delimiters,$string) {
    return explode(
        $delimiters[0],
        strtr(
            $string,
            array_combine(
                array_slice(    $delimiters, 1  ),
                array_fill(
                    0,
                    count($delimiters)-1,
                    array_shift($delimiters)
                )
            )
        )
    );
}

È un po 'illeggibile, immagino, ma l'ho provato come funzionante qui.

One-liner ftw!


11

Non strtok()funzionerebbe per te?


1
vedendo che il suo delimitatore è 'vs', questo potrebbe non funzionare come dice php docu: strtok () divide una stringa (str) in stringhe più piccole (token), con ogni token delimitato da qualsiasi carattere da token. e 'vs' contiene due caratteri
mikewasmike

1
questa sarebbe una risposta migliore se includessi una spiegazione o un esempio. così com'è, è più un commento ...
Billynoah

8

Puoi semplicemente usare il seguente codice:

$arr=explode('sep1',str_replace(array('sep2','sep3','sep4'),'sep1',$mystring));


2

Lo faccio in questo modo ...

public static function multiExplode($delims, $string, $special = '|||') {

    if (is_array($delims) == false) {
        $delims = array($delims);
    }

    if (empty($delims) == false) {
        foreach ($delims as $d) {
            $string = str_replace($d, $special, $string);
        }
    }

    return explode($special, $string);
}

questo è quello che stavo cercando
Manojkiran.

2

Cosa ne pensi di questo?

/**
 * Like explode with multiple delimiters. 
 * Default delimiters are: \ | / and ,
 *
 * @param string $string String that thould be converted to an array.
 * @param mixed $delimiters Every single char will be interpreted as an delimiter. If a delimiter with multiple chars is needed, use an Array.
 * @return array. If $string is empty OR not a string, return false
 */
public static function multiExplode($string, $delimiters = '\\|/,') 
{
  $delimiterArray = is_array($delimiters)?$delimiters:str_split($delimiters);
  $newRegex = implode('|', array_map (function($delimiter) {return preg_quote($delimiter, '/');}, $delimiterArray));
  return is_string($string) && !empty($string) ? array_map('trim', preg_split('/('.$newRegex.')/', $string, -1, PREG_SPLIT_NO_EMPTY)) : false;
}

Nel tuo caso dovresti usare un array per il parametro $ delimiters. Quindi è possibile utilizzare più caratteri come un delimitatore.

Se non ti interessa trascinare gli spazi nei risultati, puoi rimuovere la array_map('trim', [...] )parte nella riga di ritorno. (Ma non essere un cavillo in questo caso. Tienilo preg_splitdentro.)

Versione PHP richiesta: 5.3.0 o successiva.

Puoi provarlo qui


1

Avrai dei problemi (e se avessi questa stringa: per esempio "vs @ mele") usando questo metodo di separazione, ma se iniziamo affermando che ci hai pensato e che hai risolto tutte quelle possibili collisioni, potresti semplicemente sostituire tutte le occorrenze di $delimiter[1]to $delimiter[n]con $delimiter[0], e poi dividere su quella prima?


1

Se il tuo delimitatore è solo di caratteri, puoi usarlo strtok, che qui sembra essere più adatto. Nota che devi usarlo con un whileloop per ottenere gli effetti.


0

Questo funzionerà:

$stringToSplit = 'This is my String!' ."\n\r". 'Second Line';
$split = explode (
  ' ', implode (
    ' ', explode (
      "\n\r", $stringToSplit
    )
  )
);

Come puoi vedere, per prima cosa incolla le parti esplose insieme a uno spazio, per poi separarlo di nuovo, questa volta portando gli spazi con sé.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.