Php plusieurs délimiteurs dans exploser

146

J'ai un problème, j'ai un tableau de chaînes et je veux exploser dans un délimiteur différent. Par exemple

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

et j'ai besoin d'un tableau qui explose en @ ou vs.

J'ai déjà écrit une solution, mais si tout le monde a une meilleure solution, veuillez poster ici.

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;
}
OH LA LA
la source
Je n'ai jamais vu de question avec des personnes donnant des réponses telles que "Et à propos de ça", "Et à propos de ça"
HosseyNJF

Réponses:

290

qu'en est-il de l'utilisation

$ sortie = preg_split ("/ (@ | vs) /", $ entrée);
SergeS
la source
Incroyable. Je me demande comment cela se explode()
compare à des
6
Peu importe, si vous voulez créer un système volumineux avec une analyse de chaîne dure, le moyen le plus efficace est son propre analyseur. Sinon, cela n'a pas beaucoup d'effet sur la vitesse du système, mais vous préférez utiliser le moyen le plus simple pour vous (pour être rentable)
SergeS
9
Notez que certains caractères doivent être échappés pour fonctionner (comme /, ?). Par exemple: preg_split("/(\/|\?|=)/", $foo);.
kenorb
preg_split renvoie un tableau indexé. Est-il possible de revenir associatif? Par exemple $str='/x/1/2/3/4/5/y/100/200/z/777'; preg_split("/(x|y|z|)/", $str); et pour voirarray('x'=>'1/2/3/4/5', 'y'=>'100/200', 'z'=>'777')
LINKeRxUA
2
J'ai trouvé que les espaces entre / (et que ) /preg_split ne fonctionnait pas. J'ai dû supprimer les espaces puis cela a fonctionné comme prévu (en utilisant PHP 7)
Boardy
69

Vous pouvez prendre la première chaîne, remplacer toutes les @par vsusing str_replace, puis exploser vsou vice versa.

John Ballinger
la source
1
Solution facile, a fini par l'utiliser pour le code Json pour remplacer "}}" par "|". Sale mais efficace :)!
Baldráni
5
what a genius: D
Deadpool
cela ne fonctionnera pas correctement lorsqu'un délimiteur est un sur-ensemble de l'autre ( (@|@!)cas par exemple)
2
@vaxquis Oui, ce sera le cas. str_replace ('@!', '@', $ str); Assurez-vous de commencer par le délimiteur le plus unique.
John Ballinger
@JohnBallinger Non, ce ne sera pas le cas - vous avez proposé une autre solution, qui montre clairement que la solution d' origine ne fonctionnera pas correctement et que votre idée est imparfaite. Imaginez que vous ne savez pas lequel est le sur-ensemble d'un autre. Il faudrait créer une autre ligne de code pour vérifier cela, etc. Bien que je déteste les expressions régulières en général, c'est un cas où c'est la meilleure solution en termes de maintenabilité et de simplicité.
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] => )
// )

Source: php @ metehanarslan à php.net

bizauto
la source
14

Que diriez-vous d'utiliser strtr()pour remplacer tous vos autres délimiteurs par le premier?

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

C'est un peu illisible, je suppose, mais je l'ai testé comme fonctionnant ici.

One-liners ftw!

Aubry
la source
11

Cela ne strtok()fonctionnerait pas pour vous?

Mchl
la source
1
vu que son délimiteur est «vs», cela peut ne pas fonctionner comme le dit php docu: strtok () divise une chaîne (str) en chaînes plus petites (jetons), chaque jeton étant délimité par n'importe quel caractère du jeton. et 'vs' contient deux caractères
mikewasmike
1
ce serait une meilleure réponse si vous incluiez une explication ou un exemple. comme il est, c'est plus un commentaire ...
billynoah
8

Vous pouvez simplement utiliser le code suivant:

$arr=explode('sep1',str_replace(array('sep2','sep3','sep4'),'sep1',$mystring));
Samer Ata
la source
2

Je le fais de cette façon ...

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
la source
c'est ce que je cherchais
Manojkiran.A
2

Que dis-tu de ça?

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

Dans votre cas, vous devriez utiliser un tableau pour le paramètre $ delimiters. Ensuite, il est possible d'utiliser plusieurs caractères comme un seul délimiteur.

Si vous ne vous souciez pas des espaces de fin dans vos résultats, vous pouvez supprimer la array_map('trim', [...] )partie de la ligne de retour. (Mais ne soyez pas un chipoteur dans ce cas. Gardez le preg_splitdedans.)

Version PHP requise: 5.3.0 ou supérieure.

Vous pouvez le tester ici

UN F
la source
1

Vous allez avoir quelques problèmes (que se passe-t-il si vous avez cette chaîne: "vs @ pommes" par exemple) en utilisant cette méthode de séparation, mais si nous commençons par dire que vous avez pensé à cela et que vous avez corrigé toutes ces éventuelles collisions, vous pouvez simplement remplacer toutes les occurrences de $delimiter[1]à $delimiter[n]par $delimiter[0], puis vous séparer de la première?

Nanne
la source
1

Si votre délimiteur n'est que des caractères, vous pouvez utiliser strtok, ce qui semble être plus adapté ici. Notez que vous devez l'utiliser avec une whileboucle pour obtenir les effets.

Hoàng Long
la source
0

Cela fonctionnera:

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

Comme vous pouvez le voir, il colle d'abord les parties éclatées \ n \ r avec un espace, pour ensuite le découper à nouveau, cette fois en emportant les espaces avec lui.

Xesau
la source