Jak mogę umieścić ciągi w tablicy, podzielone według nowej linii?

220

W mojej bazie danych mam ciąg znaków z podziałem linii. Chcę przekonwertować ten ciąg na tablicę i dla każdej nowej linii przeskocz o jedno miejsce indeksu w tablicy.

Jeśli ciąg jest:

My text1
My text2
My text3

Chcę, aby wynik był następujący:

Array
(
    [0] => My text1
    [1] => My text2
    [2] => My text3
)
Johan
źródło
1
Nie znam PHP, ale zwykle dla ciągów jest funkcja „split”. Działa to tak: array = split (string, "\ n")
Sedat Kapanoglu
Prawdopodobnie najpierw powinieneś znormalizować nowe linie. Ta metoda s($yourString)->normalizeLineEndings()jest dostępna w witrynie github.com/delight-im/PHP-Str (biblioteka na licencji MIT), która zawiera wiele innych przydatnych pomocników łańcucha. Możesz rzucić okiem na kod źródłowy.
caw

Odpowiedzi:

290

Możesz użyć tej explodefunkcji, używając „ \n” jako separatora:

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

Na przykład, jeśli masz ten fragment kodu:

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

Otrzymasz ten wynik:

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


Zauważ, że musisz użyć podwójnego cudzysłowu , więc \njest on interpretowany jako podział wiersza.
(Więcej informacji na tej stronie podręcznika).

Pascal MARTIN
źródło
52
Zamiast tego \nmożesz użyć predefiniowanej stałej PHP_EOL.
Tim
40
Proszę, bądź ostrożny z tym rozwiązaniem, ponieważ nie działa na wszystkich nowych liniach. Odniosłem największy sukces z odpowiedzią Davida
Maurice
1
Musisz podzielić się na \ n lub \ r, aby móc obsługiwać wszelkiego rodzaju teksty - będzie to działać tylko z linuksem i oknami nowej linii. Nowe wiersze dla komputerów Mac zostaną zignorowane! (\ r)
Steve Horvath
1
Wydaje mi się, że odpowiedź / komentarz Timsa jest niewłaściwy, ponieważ będzie to pasować tylko do łamania linii w TWOIM systemie, ale kiedy otrzymasz ciągi, które mają łamanie linii z innych systemów, to nie zadziała! Miałem ten problem z e
Asara
7
Nie ma tej odpowiedzi, a komentarze do tej odpowiedzi są NIEPRAWIDŁOWE! Ponieważ nie uwzględnia to znaku nowej linii systemu operacyjnego, zwłaszcza nie PHP_EOL. Musisz użyć preg_split("/\\r\\n|\\r|\\n/", $value).
kjdion84
330

Zawsze używałem tego z wielkim sukcesem:

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

(zaktualizowane do ostatniego \ r, dzięki @LobsterMan)

David
źródło
11
Ta odpowiedź powinna być na górze zamiast Pascala. Ten nie działał we wszystkich przypadkach!
Jithesh Kt
1
Oto odpowiedź. Zweryfikowany jest NIEPRAWIDŁOWY. Cóż, hesselbom też to ma ... Możesz także użyć tego odpowiednika: preg_split ('/ \ n | \ r /', $ string, -1, PREG_SPLIT_NO_EMPTY); ze względu na piękno :) Dlaczego to jedyna dobra odpowiedź? Ponieważ nie możesz założyć, jaki typ końca linii otrzymasz: Mac (\ r), Windows (\ r \ n) lub Unix (\ n).
Ninj
2
\R mecze \n , \ri\r\n
mpen
1
Lub krócej/\r?\n/
Jason Schilling
Ten przykład jest poprawny, ponieważ nie można po prostu wykonać żadnej operacji podziału opartej na pojedynczym znaku. Jeśli to zrobisz, po uruchomieniu „\ r” lub „\ n” skończy się zbędna pusta linia w przypadku zakończenia systemu Windows „\ r \ n”. Ważne jest, aby najpierw przetestować dwuznakowy separator Windows.
AndresRohrAtlasInformatik
281

Podział linii jest różnie definiowany na różnych platformach, \ r \ n, \ r lub \ n.

Używając RegExp do podzielenia łańcucha możesz dopasować wszystkie trzy za pomocą \ R

Więc dla twojego problemu:

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

To by pasowało do podziałów linii w systemach Windows, Mac i Linux!

hesselbom
źródło
3
Użyłem tego również zamiast zaakceptowanej odpowiedzi i innych odpowiedzi w tym wątku. Pozostawiając ten komentarz jako informacyjny.
Seth Malaki
3
W rzeczywistości to nie działało dla mnie. Czasami znaki nowej linii są nadal obecne w kluczach tablicy.
Maurice
32
Wystarczy użyć$array = preg_split ('/\R/', $string);
Jan Goyvaerts
18
Czasami nie działa! preg_split("/\r\n|\n|\r/", $string)lepszy wybór
Alexey B.
34

PHP zna już znaki nowego wiersza obecnego systemu. Wystarczy użyć stałej EOL.

explode(PHP_EOL,$string)
voidstate
źródło
18
Tak, ale można edytować plik lub jak w tym przykładzie pozycję db w systemie Windows, a następnie użyć go na przykład w systemie Linux. Myślę, że ogólne podejście byłoby bardziej odpowiednie.
Cranio
Nie jestem pewien, czy to prawda. Jeśli pole tekstowe na stronie internetowej zostanie przesłane, może mieć różne znaki końca wiersza w zależności od przeglądarki użytkownika, a nie systemu operacyjnego serwera. Bez względu na to, jakiego systemu operacyjnego używasz, musisz być w stanie przeanalizować wszystko. Zakłada się, że robisz rzeczy sieciowe.
Magmatic,
Być może będziesz musiał użyć trim()wynikowych ciągów, aby usunąć wszelkie zbędne białe znaki.
Tim
30

Alternatywą dla odpowiedzi Davids'a, która jest szybsza (znacznie szybsza), jest użycie str_replacei explode.

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

Co się dzieje:
Ponieważ podziały linii mogą mieć różne formy, I str_replace\ r \ n, \ n \ r, i \ r z \ n zamiast tego (i oryginalne \ n są zachowane).
Następnie eksploduj \ni masz wszystkie linie w tablicy.

Zrobiłem test porównawczy na src tej strony i podzieliłem linie 1000 razy w pętli for i:
preg_replacewziąłem średnią z 11 sekund
str_replace & explodewziąłem średnią z około 1 sekundy

Więcej szczegółów i informacji bencmark na moim forum

Trzcina
źródło
Twój link do forum (i cała domena) wydaje się nie działać
Nikita 웃
19

David: Świetny kierunek, ale nie trafiłeś. to działało dla mnie:

$array = preg_split("/(\r\n|\n|\r)/", $string);
LobsterMan
źródło
11

Nie potrzebujesz funkcji preg_ * ani wzorców preg, ani str_replace wewnątrz itp., Aby pomyślnie rozbić ciąg znaków na tablicę przez nowe linie. We wszystkich scenariuszach, czy to Linux / Mac, czy m $, wystarczy.

<?php 

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

?>

PHP_EOL to stała przechowująca znaki łamania linii używane przez platformę serwerową.

Straszny
źródło
3
plik może pochodzić z innego systemu z różnymi nowymi liniami, w szczególności w środowisku sieciowym, dla którego jest używany PHP
Luca C.
To jest właśnie powód, dla którego ta stała istnieje i rozwiązuje ten konkretny problem.
Spooky
jeśli pobierzesz plik z systemu Windows, nie będzie on zgodny z plikiem z systemu Unix lub Mac, prawda?
Luca C.,
Jeśli używasz czystego utf-8 przez cały czas, wszędzie, normalnie dołączone pliki utf8 i nie masz nic poza PHP_EOL wewnątrz twojego kodu do wykrywania przerwania linii, zostanie on dopasowany zgodnie z opisem i nie wystąpi nieprzewidziane zachowanie. Pamiętaj, że nie tylko ja krzyczę i żądam tego. Użyteczność PHP_EOL jest dość potwierdzona.
Spooky
1
W twoim przypadku, jeśli źródła pochodzą z innego miejsca i nie są dobrze uformowane, cokolwiek, być może lepiej jest użyć str_replace (szybszego niż regexp). ... w sumie, czy to wyrażenie regularne. lub str_replace lub PHP_EOL, jest jedno dobre stare zdanie: „Jeśli to działa - nie dotykaj go!”. :)
Spooky
9
explode("\n", $str);

„(Zamiast”) jest dość ważne, ponieważ inaczej, łamanie linii nie zostanie zinterpretowane.

Damien MATHIEU
źródło
9

StackOverflow nie pozwoli mi skomentować odpowiedzi hesselbom (niewystarczająca reputacja), więc dodaję własną ...

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

Działa to dla mnie najlepiej, ponieważ automatycznie eliminuje początkowe (drugie \ s *) i końcowe (pierwsze \ s *) białe znaki, a także pomija puste linie (flaga PREG_SPLIT_NO_EMPTY).

- = OPCJE = -

Jeśli chcesz zachować wiodące białe znaki, po prostu pozbądź się sekund \ s * i zamiast tego ustaw rtrim () ...

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

Jeśli chcesz zachować puste wiersze, pozbądź się NULL (to tylko symbol zastępczy) i flagi PREG_SPLIT_NO_EMPTY, tak jak ...

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

Lub utrzymywanie zarówno wiodących białych znaków, jak i pustych linii ...

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

Nie widzę żadnego powodu, dla którego chciałbyś kiedykolwiek pozostawić końcowe białe znaki, więc sugeruję pozostawienie tam pierwszych znaków. Ale jeśli wszystko, czego chcesz, to podział według nowej linii (jak sugeruje tytuł), jest TO TAKIE proste (jak wspomniał Jan Goyvaerts) ...

$array = preg_split('/\R/', $text);
Deen Foxx
źródło
mModyfikator nie jest naprawdę potrzebne to jest? Czy to nie dotyczy tylko ^i $?
mpen
@mpen Tak, uważam, że masz rację. Właśnie nosiłem go wraz z wersją hesselbom. Zmienię mój post.
Deen Foxx,
7
<anti-answer>

Jak podano w innych odpowiedziach, użyj exploderaczej niż splitdlatego, że od PHP 5.3.0 splitjest przestarzały. tzn. NIE jest to sposób, w jaki chcesz to zrobić:

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

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

</anti-answer>
Tomek
źródło
3

Dla każdego, kto próbuje wyświetlić cronjobs w crontabie i denerwuje się, jak oddzielić każdą linię, skorzystaj z explode:

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

użycie '\ n' wydaje się nie działać, ale chr (10) działa dobrze: D

miej nadzieję, że to oszczędza komuś bólu głowy.

Jeff
źródło
Cześć Jeff, witamy w SO. Powinieneś przepisać to jako pytanie i odpowiedź, a nie odpowiedź na pytanie kogoś innego. To jest strona pytań i odpowiedzi, a nie ogólne forum. Zajrzyj do FAQ - stackoverflow.com/faq
Rebecca Scott,
Używanie '\n'nie działa, ponieważ sekwencje specjalne nie są interpretowane w pojedynczych cudzysłowach, zamiast "\n"tego należy użyć podwójnych cudzysłowów: zamiast 'n'Read php.net/manual/en/language.types.string.php
Christopher K.
2

możesz użyć tego:

 \str_getcsv($str,PHP_EOL);
parisssss
źródło
2

Możesz zrobić $ string = nl2br ($ string), aby zmienić podział linii na

<br />. 

W ten sposób nie ma znaczenia, czy system używa \ r \ n lub \ n lub \ r

Następnie możesz wprowadzić go do tablicy:

$array = explode("<br />", $string);
Sandor
źródło
Uwaga: nl2br nie zastępuje podziału linii ... wstawia znacznik podziału przed każdym podziałem linii. Tak więc wszystkie elementy tablicy inne niż pierwszy zaczną się od podziału linii. Jeśli to nie ma znaczenia, ta metoda jest najszybsza. Jeśli to ma znaczenie, odpowiedź Jakara jest najszybsza.
Aust
2

To jest mój sposób:

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

Spowoduje to również pominięcie wszystkich pustych linii.

Axel
źródło
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";
}

prawdziwa tablica:

$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

Umieść online:

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

antylopa
źródło
Dodaj wyjaśnienie z odpowiedzią na pytanie, w jaki sposób ta odpowiedź pomaga OP w rozwiązaniu bieżącego problemu
ρяσсρєя K
1

Znalazłem to w dokumentach 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
źródło
0

Ta metoda zawsze działa dla mnie:

$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'])));

źródło
1
Uwielbiam przeklinanie jako część kodu. :) W każdym razie zamiana na \ n jest prostsza i bezpieczniejsza (spójrz na inne odpowiedzi).
Stefan Reich,
0

Użycie tylko pakietu „podstawowego” jest również rozwiązaniem dla prostych przypadków:

> 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
źródło
-6

Używając dowolnego znaku specjalnego między ciągiem lub łamaniem wiersza \nza pomocą PHP, możemy to osiągnąć.

yasin
źródło