¿Cómo puedo poner cadenas en una matriz, divididas por una nueva línea?

220

Tengo una cadena con saltos de línea en mi base de datos. Quiero convertir esa cadena en una matriz y, por cada nueva línea, saltar un lugar de índice en la matriz.

Si la cadena es:

My text1
My text2
My text3

El resultado que quiero es este:

Array
(
    [0] => My text1
    [1] => My text2
    [2] => My text3
)
Johan
fuente
1
No conozco PHP, pero generalmente hay una función llamada "split" para cadenas. Funciona así: array = split (string, "\ n")
Sedat Kapanoglu
Debería normalizar las nuevas líneas primero, probablemente. El método s($yourString)->normalizeLineEndings()está disponible con github.com/delight-im/PHP-Str (biblioteca bajo licencia MIT) que tiene muchos otros ayudantes de cadena útiles. Es posible que desee echar un vistazo al código fuente.
graznar

Respuestas:

290

Puede usar la explodefunción, usando " \n" como separador:

$your_array = explode("\n", $your_string_from_db);

Por ejemplo, si tiene este código:

$str = "My text1\nMy text2\nMy text3";
$arr = explode("\n", $str);
var_dump($arr);

Obtendría esta salida:

array
  0 => string 'My text1' (length=8)
  1 => string 'My text2' (length=8)
  2 => string 'My text3' (length=8)


Tenga en cuenta que debe usar una cadena entre comillas dobles , por \nlo que en realidad se interpreta como un salto de línea.
(Vea esa página del manual para más detalles).

Pascal MARTIN
fuente
52
En lugar de \nusted, puede usar la constante predefinida PHP_EOL.
Tim
40
Todos, tengan cuidado con esta solución, ya que no funciona en todas las líneas nuevas. He tenido el mayor éxito con la respuesta de David
Maurice
1
Debe dividir en \ n o \ r para poder manejar todo tipo de textos; esto solo funcionará con las líneas nuevas de Linux y Windows. ¡Las nuevas líneas de Mac no se tendrán en cuenta! (\ r)
Steve Horvath
1
Supongo que la respuesta / comentario de Tims no está bien, porque esto solo coincidirá con el salto de línea en SU ​​sistema, pero cuando obtiene cadenas que tienen saltos de línea de otros sistemas, ¡no funcionará! Tuve este problema con los correos electrónicos
Asara
77
¡No, esta respuesta y los comentarios sobre esta respuesta son INCORRECTOS! Porque esto no tiene en cuenta el carácter de nueva línea del sistema operativo, especialmente no PHP_EOL. Debes usar preg_split("/\\r\\n|\\r|\\n/", $value).
kjdion84
331

Siempre he usado esto con gran éxito:

$array = preg_split("/\r\n|\n|\r/", $string);

(actualizado con el \ r final, gracias @LobsterMan)

David
fuente
11
Esta respuesta debe estar en la parte superior en lugar de la de Pascal. ¡Ese no funcionó en todos los casos!
Jithesh Kt
1
Esta es la respuesta. El validado es incorrecto. Bueno, hesselbom también lo tiene ... También podría usar este equivalente: preg_split ('/ \ n | \ r /', $ string, -1, PREG_SPLIT_NO_EMPTY); por el bien de la belleza :) ¿Por qué es esta la única buena respuesta? Porque no puede asumir qué tipo de final de línea obtendrá: Mac (\ r), Windows (\ r \ n) o Unix (\ n).
Ninj
2
\R partidos \n , \ry\r\n
mpen
1
O más corto/\r?\n/
Jason Schilling el
Este ejemplo es correcto porque no puede tomar cualquier operación dividida que se base solo en un solo carácter. Si lo hiciera, activando '\ r' o '\ n', terminará con una línea vacía superflua en caso de un final de Windows "\ r \ n". Y es importante que el separador de Windows de dos caracteres se pruebe primero.
AndresRohrAtlasInformatik
281

Un salto de línea se define de manera diferente en diferentes plataformas, \ r \ n, \ r o \ n.

Usando RegExp para dividir la cadena, puede unir los tres con \ R

Entonces para tu problema:

$array = preg_split ('/$\R?^/m', $string);

¡Eso coincidiría con los saltos de línea en Windows, Mac y Linux!

hesselbom
fuente
3
También utilicé esto en lugar de la respuesta aceptada y cualquier otra respuesta en este hilo. Solo dejo este comentario como informativo.
Seth Malaki
3
En realidad, esto no funcionó para mí. A veces, las nuevas líneas todavía están presentes en las teclas de matriz.
Maurice
32
Solo use$array = preg_split ('/\R/', $string);
Jan Goyvaerts
18
No funciona a veces! preg_split("/\r\n|\n|\r/", $string)mejor opción
Alexey B.
34

PHP ya conoce los caracteres de nueva línea del sistema actual. Solo usa la constante EOL.

explode(PHP_EOL,$string)
estado nulo
fuente
18
Sí, pero se puede editar un archivo o, como en este ejemplo, una entrada db en Windows y luego usarlo en un sistema Linux, por ejemplo. Creo que un enfoque general sería más adecuado.
Cranio
No estoy seguro de que esto sea correcto. Si se envía un área de texto en una página web, podría tener diferentes caracteres de fin de línea dependiendo del navegador del usuario, no del sistema operativo del servidor. Entonces, no importa qué sistema operativo esté utilizando, deberá poder analizar cualquier cosa. Esto supone que estás haciendo cosas web, por supuesto.
Magmatic
Es posible que deba usar trim()las cadenas resultantes para eliminar cualquier espacio en blanco extraño.
Tim
30

Una alternativa a la respuesta de Davids que es más rápida (mucho más rápido) es usar str_replacey explode.

$arrayOfLines = explode("\n",
                    str_replace(["\r\n","\n\r","\r"],"\n",$str)
            );

Lo que sucede es que,
dado que los saltos de línea pueden tener diferentes formas, I str_replace\ r \ n, \ n \ r y \ r con \ n en su lugar (y se conservan los originales \ n).
Luego explota \ny tienes todas las líneas en una matriz.

Hice un punto de referencia en el src de esta página y dividí las líneas 1000 veces en un bucle for y:
preg_replacetomó un promedio de 11 segundos
str_replace & explodetomó un promedio de aproximadamente 1 segundo

Más detalles e información de referencia en mi foro

Junco
fuente
El enlace de su foro (y todo el dominio) parece estar inactivo
Nikita 웃
19

David: Gran dirección, pero te perdiste \ r. esto funcionó para mí:

$array = preg_split("/(\r\n|\n|\r)/", $string);
Langosta
fuente
11

No necesita funciones preg_ * ni patrones preg ni str_replace dentro, etc. para dividir con éxito una cadena en una matriz mediante nuevas líneas. En todos los escenarios, ya sea Linux / Mac o m $, esto servirá.

<?php 

 $array = explode(PHP_EOL, $string);
 // ...  
 $string = implode(PHP_EOL, $array);

?>

PHP_EOL es una constante que contiene los caracteres de salto de línea utilizados por la plataforma del servidor.

Escalofriante
fuente
3
el archivo podría provenir de otro sistema con diferentes líneas nuevas, particularmente en un entorno de red para el que se usa PHP
Luca C.
Cuál es exactamente la razón por la que esta constante existe ... y maneja ese problema en particular.
Espeluznante
Si toma un archivo de Windows, no coincide con un archivo de Unix o Mac, ¿verdad?
Luca C.
Si está utilizando utf-8 puro todo el tiempo, en todas partes, los archivos utf8 incluidos, normalmente, y no tiene nada más que PHP_EOL dentro del código suyo para las detecciones de salto de línea, se combinará como se describe y no se producirá ningún comportamiento imprevisto. Tenga en cuenta que no solo estoy gritando y reclamando esto. La usabilidad de PHP_EOL está bastante confirmada.
Espeluznante
1
En su caso, si las fuentes provienen de otro lugar y no están bien formadas, lo que sea, tal vez sea mejor si usa str_replace (más rápido que regexp). ... en general, ya sea regexp. o str_replace o PHP_EOL, hay una buena frase que dice: "Si funciona, ¡no la toques!". :)
Spooky
9
explode("\n", $str);

El "(en lugar de ') es bastante importante, de lo contrario, el salto de línea no se interpretará.

Damien MATHIEU
fuente
9

StackOverflow no me permitirá comentar la respuesta de hesselbom (no hay suficiente reputación), así que estoy agregando la mía ...

$array = preg_split('/\s*\R\s*/', trim($text), NULL, PREG_SPLIT_NO_EMPTY);

Esto funcionó mejor para mí porque también elimina el espacio en blanco inicial (segundo \ s *) y posterior (primero \ s *) automáticamente y también omite las líneas en blanco (el indicador PREG_SPLIT_NO_EMPTY).

- = OPCIONES = -

Si desea mantener el espacio en blanco inicial, simplemente elimine el segundo \ s * y conviértalo en un rtrim () en su lugar ...

$array = preg_split('/\s*\R/', rtrim($text), NULL, PREG_SPLIT_NO_EMPTY);

Si necesita mantener líneas vacías, elimine el NULL (es solo un marcador de posición) y el marcador PREG_SPLIT_NO_EMPTY, así ...

$array = preg_split('/\s*\R\s*/', trim($text));

O mantener tanto los espacios en blanco iniciales como las líneas vacías ...

$array = preg_split('/\s*\R/', rtrim($text));

No veo ninguna razón por la que quieras seguir dejando espacios en blanco, así que sugiero dejar el primer \ s * allí. Pero, si todo lo que quieres es dividir por una nueva línea (como sugiere el título), es ESTE simple (como lo menciona Jan Goyvaerts) ...

$array = preg_split('/\R/', $text);
Deen Foxx
fuente
El mmodificador no es realmente necesario, ¿verdad? ¿Eso no solo afecta ^y $?
mpen
@mpen Sí, creo que tienes razón. Lo llevé junto con la versión de hesselbom. Editaré mi publicación.
Deen Foxx
7
<anti-answer>

Como han especificado otras respuestas, asegúrese de usar en explodelugar de splitporque a partir de PHP 5.3.0 splitestá en desuso. es decir, lo siguiente NO es la forma en que desea hacerlo:

$your_array = split(chr(10), $your_string);

LF = "\ n" = chr (10), CR = "\ r" = chr (13)

</anti-answer>
Tom
fuente
3

Para cualquiera que intente mostrar cronjobs en un crontab y se sienta frustrado sobre cómo separar cada línea, use explotar:

$output = shell_exec('crontab -l');
$cron_array = explode(chr(10),$output);

el uso de '\ n' no parece funcionar pero chr (10) funciona bien: D

Espero que esto le ahorre a alguien algunos dolores de cabeza.

Jeff
fuente
Hola Jeff, bienvenido a SO. Debería reescribir esto como una pregunta y respuesta, en lugar de una respuesta a la pregunta de otra persona. Este es un sitio de preguntas y respuestas, no un foro general. Eche un vistazo a las preguntas frecuentes - stackoverflow.com/faq
Rebecca Scott
El uso '\n'no funciona porque las secuencias de escape no se interpretan entre comillas simples, en su lugar debe usar comillas dobles: en "\n"lugar de 'n'Leer php.net/manual/en/language.types.string.php
Christopher K.
2

puedes usar esto:

 \str_getcsv($str,PHP_EOL);
parisssss
fuente
2

Puede hacer un $ string = nl2br ($ string) para que su salto de línea se cambie a

<br />. 

De esta manera, no importa si el sistema usa \ r \ n o \ n o \ r

Luego puede alimentarlo en una matriz:

$array = explode("<br />", $string);
Sandor
fuente
Nota: nl2br no reemplaza los saltos de línea ... solo inserta una etiqueta de salto antes de cada salto de línea. Por lo tanto, todos los elementos de la matriz que no sean el primero comenzarán con un salto de línea. Si eso no te importa, entonces este método es el más rápido. Si eso importa, la respuesta de Jakar es la más rápida.
Aust
2

Esa es mi manera:

$lines = preg_split('/[\r\n]+/', $db_text, NULL, PREG_SPLIT_NO_EMPTY);

Esto también omitirá todas las líneas vacías.

Axel
fuente
1
$str = "My text1\nMy text2\nMy text3";
$arr = explode("\n", $str);

foreach ($arr as $line_num => $line) {
    echo "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}

matriz verdadera:

$str = "My text1\nMy text2\nMy text3";
$arr = explode("\n", $str);

$array = array(); // inisiasi variable array in format array

foreach ($arr as $line) { // loop line by line and convert into array
    $array[] = $line;
};

print_r($array); // display all value

echo $array[1]; // diplay index 1

Insertar en línea:

body, html, iframe { 
  width: 100% ;
  height: 100% ;
  overflow: hidden ;
}
<iframe src="https://ideone.com/vE1gst" ></iframe>

antílope
fuente
Agregue alguna explicación con la respuesta de cómo esta respuesta ayuda a OP a solucionar el problema actual
ρяσѕρєя K
1

Recogí esto en los documentos php:

<?php
  // split the phrase by any number of commas or space characters,
  // which include " ", \r, \t, \n and \f

  $keywords = preg_split("/[\s,]+/", "hypertext language, programming");
  print_r($keywords);
?>
korwalskiy
fuente
0

Este método siempre funciona para mí:

$uniquepattern="gd$#%@&~#"//Any set of characters which you dont expect to be present in user input $_POST['text'] better use atleast 32 charecters.
$textarray=explode($uniquepattern,str_replace("\r","",str_replace("\n",$uniquepattern,$_POST['text'])));

fuente
1
Me encantan las palabrotas como parte del código. :) De todos modos, reemplazar con \ n es más simple y más seguro (mira las otras respuestas).
Stefan Reich
0

Usar solo el paquete 'base' también es una solución para casos simples:

> s <- "a\nb\rc\r\nd"
> l <- strsplit(s,"\r\n|\n|\r")
> l  # the whole list...
[[1]]
[1] "a" "b" "c" "d"
> l[[1]][1] # ... or individual elements
[1] "a"
> l[[1]][2]
[1] "b"
> fun <- function(x) c('Line content:', x) # handle as you wish
> lapply(unlist(l), fun)
Roque
fuente
-6

Usando cualquier carácter especial entre la cadena o el salto de línea \nusando PHP explotar podemos lograr esto.

yasin
fuente