Php delimitadores múltiples en explosión


146

Tengo un problema, tengo una matriz de cadenas y quiero explotar en un delimitador diferente. Por ejemplo

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

y necesito una matriz que explote en @ o vs.

Ya escribí una solución, pero si todos tienen una solución mejor, publique aquí.

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

Nunca vi una pregunta con personas dando respuestas como "¿Qué tal esto?", "¿Qué pasa con eso?"
HosseyNJF

Respuestas:


290

¿Qué hay de usar

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

Asombroso. explode()
Me

66
No importa, si desea hacer un sistema grande con análisis de cadenas rígidas, la forma más efectiva es el propio analizador. De lo contrario, no tiene mucho efecto en la velocidad del sistema, pero prefiere usar la forma más fácil para usted (para ser efectivo)
SergeS

9
Tenga en cuenta que algunos caracteres deben escapar al trabajo (como /, ?). Por ejemplo: preg_split("/(\/|\?|=)/", $foo);.
kenorb

preg_split devuelve una matriz indexada. ¿Es posible volver asociativo? Por ejemplo $str='/x/1/2/3/4/5/y/100/200/z/777'; preg_split("/(x|y|z|)/", $str); y para verarray('x'=>'1/2/3/4/5', 'y'=>'100/200', 'z'=>'777')
LINKeRxUA

2
Encontré tener los espacios entre / (y ) /dejé que preg_split funcionara. Tuve que eliminar los espacios y luego funcionó como se esperaba (usando PHP 7)
Boardy

69

Puede tomar la primera cadena, reemplazar todo @con el vsuso str_replace, luego explotar vso viceversa.


1
Solución fácil, terminó usándolo para el código Json para reemplazar "}}" por "|". Sucio pero eficiente :)!
Baldráni

55
qué genio: D
Deadpool

esto no funcionará correctamente cuando un delimitador sea un superconjunto del otro (por ejemplo, (@|@!)caso)

2
@vaxquis Sí, lo hará. str_replace ('@!', '@', $ str); Asegúrese de comenzar con el delimitador más exclusivo.
John Ballinger el

@JohnBallinger No, no lo hará: propuso otra solución, que muestra claramente que la solución original no funcionará correctamente y que su idea es defectuosa. Imagina que no sabes cuál es el superconjunto de otro. Tendría que crear otra línea de código para verificar eso, etc. Aunque odio las expresiones regulares en general, este es un caso cuando es la mejor solución en términos de facilidad de mantenimiento y simplicidad.

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] => )
// )

Fuente: php @ metehanarslan en php.net


14

¿Qué te parece usar strtr()para sustituir todos tus otros delimitadores con el primero?

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

Supongo que es ilegible, pero lo probé porque funcionaba aquí.

One-liners ftw!


11

¿No strtok()funcionaría para ti?


1
Al ver que su delimitador es 'vs', esto puede no funcionar como dice php docu: strtok () divide una cadena (str) en cadenas más pequeñas (tokens), con cada token delimitado por cualquier carácter del token. y 'vs' contiene dos personajes
mikewasmike

1
Esta sería una mejor respuesta si incluye una explicación o ejemplo. tal como es, es más un comentario ...
billynoah

8

Simplemente puede usar el siguiente código:

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


2

Lo hago de esta manera ...

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

esto es lo que estaba buscando
Manojkiran. A

2

¿Qué tal esto?

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

En su caso, debe usar una matriz para el parámetro $ delimiters. Entonces es posible usar múltiples caracteres como un delimitador.

Si no le interesan los espacios finales en sus resultados, puede eliminar la array_map('trim', [...] )parte en la fila de retorno. (Pero no seas un discutidor en este caso. Mantén elpreg_split ).

Versión PHP requerida: 5.3.0 o superior.

Puedes probarlo aquí


1

Tendrá algunos problemas (por ejemplo, si tiene esta cadena: "vs @ apples") usando este método de separación, pero si comenzamos diciendo que ha pensado en eso y ha solucionado todas esas posibles colisiones, ¿Podrías reemplazar todas las ocurrencias de $delimiter[1]a $delimiter[n]con $delimiter[0], y luego dividirte en la primera?


1

Si su delimitador son solo caracteres, puede usarlos strtok, lo que parece encajar mejor aquí. Tenga en cuenta que debe usarlo con un whilebucle para lograr los efectos.


0

Esto funcionará:

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

Como puede ver, primero pega las partes explotadas por \ n \ r junto con un espacio, para luego cortarlo nuevamente, esta vez tomando los espacios con él.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.