Rozbij kilka ograniczników PHP

146

Mam problem, mam tablicę ciągów i chcę eksplodować w innym ograniczniku. Na przykład

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

i potrzebuję tablicy, która eksploduje w @ lub vs.

Napisałem już rozwiązanie, ale jeśli każdy ma lepsze rozwiązanie, napisz tutaj.

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;
}
O LA LA
źródło
Nigdy nie widziałem pytania, na które ludzie odpowiadaliby „Co powiesz na to”, „A co z tamtym”
HosseyNJF

Odpowiedzi:

290

co z używaniem

$ wyjście = preg_split ("/ (@ | vs) /", $ wejście);
SergeS
źródło
Niesamowity. Zastanawiam się, jak to explode()
wypada
6
Nie ma znaczenia, jeśli chcesz stworzyć duży system z twardym parsowaniem ciągów znaków, najbardziej efektywnym sposobem jest własny parser. Oterwise nie ma to większego wpływu na szybkość systemu, ale wolisz używać najłatwiejszego sposobu dla siebie (Aby być efektywnym finansowo)
SergeS
9
Zwróć uwagę, że niektóre znaki muszą zostać zmienione, aby działały (takie jak /, ?). Na przykład: preg_split("/(\/|\?|=)/", $foo);.
kenorb
preg_split zwraca tablicę indeksowaną. Czy można zwrócić asocjacyjną? Na przykład $str='/x/1/2/3/4/5/y/100/200/z/777'; preg_split("/(x|y|z|)/", $str); i do zobaczeniaarray('x'=>'1/2/3/4/5', 'y'=>'100/200', 'z'=>'777')
LINKeRxUA
2
Znalazłem spacje między / (i ) /zatrzymałem działanie preg_split. Musiałem usunąć spacje, a potem działało zgodnie z oczekiwaniami (używając PHP 7)
Boardy
69

Można wziąć pierwszy ciąg, należy wymienić wszystkie @z vsużyciem str_replace, a następnie eksplodować na vsodwrót.

John Ballinger
źródło
1
Proste rozwiązanie, skończyło się na użyciu go w kodzie Json, aby zastąpić „}}” przez „|”. Brudne, ale wydajne :)!
Baldráni
5
co za geniusz: D
Deadpool
to nie będzie działać poprawnie, gdy jeden separator jest nadzbiorem drugiego (np. (@|@!)przypadek)
2
@vaxquis Tak, będzie. str_replace ('@!', '@', $ str); Upewnij się, że zaczynasz od najbardziej unikalnego separatora.
John Ballinger,
@JohnBallinger Nie, nie będzie - zaproponowałeś inne rozwiązanie, z którego jasno wynika, że oryginalne rozwiązanie nie działa poprawnie, a Twój pomysł jest wadliwy. Wyobraź sobie, że nie wiesz, który z nich jest nadzbiorem drugiego. Będziesz musiał utworzyć kolejną linię kodu, aby to sprawdzić itp. Chociaż ogólnie nienawidzę wyrażeń regularnych, jest to przypadek, gdy jest to najlepsze rozwiązanie pod względem łatwości utrzymania i prostoty.
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] => )
// )

Źródło: php @ metehanarslan na php.net

bizauto
źródło
14

A co powiesz strtr()na zastąpienie wszystkich pozostałych separatorów pierwszym?

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

Wydaje mi się, że to trochę nieczytelne, ale przetestowałem to jako pracujące tutaj.

One-liners ftw!

Aubry
źródło
11

Nie strtok()zadziała dla Ciebie?

Mchl
źródło
1
widząc, że jego separatorem jest „vs”, może to nie działać, jak mówi php docu: strtok () dzieli ciąg (str) na mniejsze ciągi (tokeny), przy czym każdy token jest oddzielany dowolnym znakiem z tokenu. a „vs” zawiera dwie postacie
mikewasmike
1
to byłaby lepsza odpowiedź, gdybyś dołączył wyjaśnienie lub przykład. jak to jest, to raczej komentarz ...
billynoah
8

Po prostu możesz użyć następującego kodu:

$arr=explode('sep1',str_replace(array('sep2','sep3','sep4'),'sep1',$mystring));
Samer Ata
źródło
2

Robię to w ten sposób ...

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);
}
Vaci
źródło
to jest to, czego szukałem
Manojkiran.A
2

Co powiesz na to?

/**
 * 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;
}

W twoim przypadku powinieneś użyć Array dla parametru $ delimiters. Wtedy można użyć wielu znaków jako jednego separatora.

Jeśli nie interesują Cię końcowe spacje w wynikach, możesz usunąć array_map('trim', [...] )część w wierszu zwracania. (Ale nie wygłupiaj się w tym przypadku. Zachowaj preg_splitw nim).

Wymagana wersja PHP: 5.3.0 lub nowsza.

Możesz to przetestować tutaj

AF
źródło
1

Będziesz miał pewne problemy (co, jeśli masz na przykład ten ciąg: "vs @ jabłka") używając tej metody rozdzielania, ale jeśli zaczniemy od stwierdzenia, że ​​przemyślałeś to i naprawiłeś wszystkie możliwe kolizje, można po prostu zastąpić wszystkich wystąpień $delimiter[1]do $delimiter[n]z $delimiter[0], a następnie podzielone na tej pierwszej?

Nanne
źródło
1

Jeśli twoim separatorem są tylko znaki, możesz użyć strtok, który wydaje się bardziej pasować tutaj. Zauważ, że musisz użyć go z whilepętlą, aby osiągnąć efekty.

Hoàng Long
źródło
0

To zadziała:

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

Jak widać, najpierw skleja eksplodowane części \ n \ r ze spacją, a następnie ponownie je rozdziela, tym razem zabierając ze sobą spacje.

Xesau
źródło