ฉันจะใส่สตริงลงในอาร์เรย์โดยแบ่งเป็นบรรทัดใหม่ได้อย่างไร


220

ฉันมีสตริงที่มีตัวแบ่งบรรทัดในฐานข้อมูลของฉัน ฉันต้องการแปลงสตริงนั้นเป็นอาร์เรย์และสำหรับทุกบรรทัดใหม่ให้กระโดดหนึ่งดัชนีในอาร์เรย์

หากสตริงคือ:

My text1
My text2
My text3

ผลลัพธ์ที่ฉันต้องการคือ:

Array
(
    [0] => My text1
    [1] => My text2
    [2] => My text3
)

1
ฉันไม่ทราบ PHP แต่มักจะมีฟังก์ชั่นที่เรียกว่า "แยก" สำหรับสตริง มันใช้งานได้เช่นนี้: array = split (string, "\ n")
Sedat Kapanoglu

คุณควรทำให้บรรทัดใหม่เป็นปกติก่อน วิธีs($yourString)->normalizeLineEndings()นี้ใช้ได้กับgithub.com/delight-im/PHP-Str ( ไลบรารี่ภายใต้ MIT License) ซึ่งมีตัวช่วยสตริงที่มีประโยชน์อื่น ๆ อีกมากมาย คุณอาจต้องการดูรหัสต้นฉบับ
caw

คำตอบ:


291

คุณสามารถใช้explodeฟังก์ชันโดยใช้ " \n" เป็นตัวคั่น:

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

ตัวอย่างเช่นหากคุณมีรหัสชิ้นนี้:

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

คุณจะได้รับผลลัพธ์นี้:

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


โปรดทราบว่าคุณต้องใช้สตริงที่มีเครื่องหมายคำพูดคู่ดังนั้นจึง\nถูกตีความเป็นตัวแบ่งบรรทัด
(ดูหน้าคู่มือนั้นสำหรับรายละเอียดเพิ่มเติม)


52
แทนที่จะ\nใช้ค่าคงที่ที่กำหนดไว้ล่วงหน้าPHP_EOLแทน
ทิม

40
ทุกคนโปรดใช้ความระมัดระวังกับโซลูชันนี้เนื่องจากไม่สามารถใช้กับการขึ้นบรรทัดใหม่ทั้งหมด ฉันประสบความสำเร็จมากที่สุดด้วยคำตอบของดาวิด
มอริซ

1
คุณต้องแยกที่ \ n หรือ \ r เพื่อให้สามารถจัดการกับข้อความทุกประเภทได้ - ซึ่งจะทำงานกับบรรทัดใหม่ของ linux & windows เท่านั้น การขึ้นบรรทัดใหม่ของ Mac จะถูกเพิกเฉย! (\ r)
Steve Horvath

1
ฉันเดาว่า Tims คำตอบ / ความคิดเห็นไม่ถูกต้องเพราะมันจะตรงกับ linebreak ระบบของคุณ แต่เมื่อคุณได้รับสายที่มี linebreaks จากระบบอื่น ๆ มันจะไม่ทำงาน! มีปัญหากับอีเมลนี้
Asara

7
ไม่คำตอบนี้และความคิดเห็นต่อคำตอบนี้ไม่ถูกต้อง! เพราะที่นี่ไม่ได้เป็นปัจจัยในตัวละคร OS PHP_EOLขึ้นบรรทัดใหม่โดยเฉพาะอย่างยิ่งไม่ได้ preg_split("/\\r\\n|\\r|\\n/", $value)คุณต้องใช้
kjdion84

331

ฉันเคยใช้มันด้วยความสำเร็จ:

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

(อัปเดตด้วย final \ r ขอบคุณ @LobsterMan)


11
คำตอบนี้ควรอยู่ด้านบนแทนที่จะเป็นภาษา Pascal อันนั้นใช้ไม่ได้กับทุกกรณี!
Jithesh Kt

1
นี่คือคำตอบ หนึ่งที่ตรวจสอบแล้วคือผิด เอ่อ hesselbom ก็เช่นกัน ... คุณสามารถใช้สิ่งนี้เทียบเท่า: preg_split ('/ \ n | \ r /', $ string, -1, PREG_SPLIT_NO_EMPTY); เพื่อความงาม :) ทำไมนี่เป็นคำตอบเดียวที่ดี? เนื่องจากคุณไม่สามารถคาดเดาได้ว่าคุณจะได้รับปลายประเภทใด: Mac (\ r), Windows (\ r \ n) หรือ Unix (\ n)
Ninj

2
\R การแข่งขัน \n , \rและ\r\n
mpen

1
หรือสั้นกว่า/\r?\n/
Jason Schilling

ตัวอย่างนี้ถูกต้องเพราะคุณไม่สามารถแยกการดำเนินการที่อิงกับอักขระตัวเดียวได้ หากคุณทำเช่นนั้นการเรียกใช้ '\ r' หรือ '\ n' คุณจะจบลงด้วยบรรทัดว่างเปล่าที่ฟุ่มเฟือยในกรณีที่สิ้นสุด Windows "\ r \ n" และสิ่งสำคัญคือต้องมีการทดสอบตัวคั่น Windows สองอักขระก่อน
AndresRohrAtlasInformatik

281

ตัวแบ่งบรรทัดถูกกำหนดแตกต่างกันในแต่ละแพลตฟอร์ม \ r \ n, \ r หรือ \ n

การใช้ RegExp เพื่อแยกสตริงคุณสามารถจับคู่ทั้งสามด้วย \ R

ดังนั้นสำหรับปัญหาของคุณ:

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

ที่จะตรงกับตัวแบ่งบรรทัดใน Windows, Mac และ Linux!


3
ฉันใช้สิ่งนี้เช่นกันแทนที่จะเป็นคำตอบที่ยอมรับและคำตอบอื่น ๆ ในกระทู้นี้ เพียงแค่แสดงความคิดเห็นนี้เป็นข้อมูล
Seth Malaki

3
ที่จริงแล้วสิ่งนี้ไม่ได้ผลสำหรับฉัน บางครั้งขึ้นบรรทัดใหม่ซึ่งยังคงมีอยู่ในคีย์อาร์เรย์
มอริซ


32
เพียงใช้$array = preg_split ('/\R/', $string);
Jan Goyvaerts

18
บางครั้งไม่ทำงาน! preg_split("/\r\n|\n|\r/", $string)ทางเลือกที่ดีกว่า
Alexey B.

34

PHP ทราบอักขระขึ้นบรรทัดใหม่ของระบบปัจจุบันอยู่แล้ว เพียงใช้ค่าคงที่ EOL

explode(PHP_EOL,$string)

18
ใช่ แต่สามารถแก้ไขไฟล์หรือในตัวอย่างนี้รายการ db ใน Windows จากนั้นใช้มันในระบบ Linux เป็นต้น ฉันคิดว่าวิธีการทั่วไปจะเหมาะสมกว่า
Cranio

ฉันไม่แน่ใจว่าสิ่งนี้ถูกต้อง หากพื้นที่ข้อความบนหน้าเว็บได้รับการส่งอาจมีอักขระสิ้นสุดบรรทัดที่แตกต่างกันขึ้นอยู่กับเบราว์เซอร์ของผู้ใช้ไม่ใช่ระบบปฏิบัติการของเซิร์ฟเวอร์ ดังนั้นไม่ว่าคุณจะใช้ระบบปฏิบัติการใดคุณจะต้องแยกวิเคราะห์อะไรก็ได้ นี่คือการสมมติว่าคุณกำลังทำเว็บแน่นอน
Magmatic

จากนั้นคุณอาจต้องใช้trim()สตริงที่เป็นผลลัพธ์เพื่อลบช่องว่างที่ไม่เกี่ยวข้องออกไป
ทิม

30

ทางเลือกในการตอบ Davidsซึ่งเร็ว (วิธีที่เร็วกว่า) คือการใช้และstr_replaceexplode

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

สิ่งที่เกิดขึ้นคือ:
เนื่องจากการขึ้นบรรทัดใหม่อาจมาในรูปแบบที่แตกต่างกัน I str_replace\ r \ n, \ n \ r และ \ r ด้วย \ n แทน (และต้นฉบับจะถูกเก็บไว้)
จากนั้นระเบิดต่อ\nและคุณมีทุกบรรทัดในอาร์เรย์

ฉันทำเกณฑ์มาตรฐานใน src ของหน้านี้และแยกบรรทัด 1000 ครั้งในลูปและ:
preg_replaceใช้เวลาเฉลี่ย 11 วินาที
str_replace & explodeใช้เวลาเฉลี่ยประมาณ 1 วินาที

รายละเอียดเพิ่มเติมและข้อมูล bencmark ในฟอรั่มของฉัน


ลิงก์ฟอรัมของคุณ (และทั้งโดเมน) ดูเหมือนจะไม่ทำงาน
Nikita 웃

19

เดวิด: ทิศทางที่ดี แต่คุณพลาดไป สิ่งนี้ใช้ได้กับฉัน:

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

11

คุณไม่ต้องการฟังก์ชั่น preg_ * หรือรูปแบบ preg หรือ str_replace ภายใน ฯลฯ เพื่อที่จะทำสำเร็จให้แบ่งสตริงเป็นอาร์เรย์โดยการขึ้นบรรทัดใหม่ ในทุกสถานการณ์ไม่ว่าจะเป็น Linux / Mac หรือ m $ สิ่งนี้จะทำ

<?php 

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

?>

PHP_EOLเป็นค่าคงที่ของอักขระตัวแบ่งบรรทัดที่ใช้โดยแพลตฟอร์มเซิร์ฟเวอร์


3
ไฟล์อาจมาจากระบบอื่นที่มีบรรทัดใหม่ที่แตกต่างกันโดยเฉพาะอย่างยิ่งในสภาพแวดล้อมสุทธิสำหรับที่ใช้ PHP
Luca C.

ซึ่งเป็นเหตุผลตรงที่ค่าคงที่นี้มีอยู่ .. และจัดการกับปัญหาเฉพาะนั้น
Spooky

ถ้าคุณใช้ไฟล์จาก windows มันไม่ตรงกับไฟล์จาก unix หรือ mac ใช่ไหม?
Luca C.

หากคุณใช้ utf-8 ล้วนตลอดเวลาทุกที่รวมถึงไฟล์ utf8 ตามปกติและคุณไม่มีอะไรอื่นนอกจาก PHP_EOL ภายในโค้ดของคุณสำหรับการตรวจจับการแบ่งบรรทัดมันจะถูกจับคู่ตามที่อธิบายไว้และจะไม่มีพฤติกรรมที่ไม่คาดคิดเกิดขึ้น โปรดทราบว่าไม่ใช่แค่ฉันตะโกนและอ้างสิทธิ์นี้ PHP_EOL ยืนยันการใช้งานค่อนข้างดี
Spooky

1
ในกรณีของคุณหากแหล่งที่มามาจากที่อื่นและไม่ได้เกิดขึ้นอย่างดีอะไรก็ตามมันอาจจะดีกว่าถ้าคุณใช้ str_replace (เร็วกว่า regexp) ... โดยรวมไม่ว่าจะเป็น regexp หรือ str_replace หรือ PHP_EOL มีประโยคเก่า ๆ หนึ่งประโยคที่พูดว่า: "ถ้ามันใช้ได้ - อย่าแตะต้อง!" :)
Spooky

9
explode("\n", $str);

"(แทนที่จะเป็น ') มีความสำคัญมากไม่เช่นนั้นการขึ้นบรรทัดใหม่จะไม่ถูกตีความ


9

StackOverflow จะไม่อนุญาตให้ฉันแสดงความคิดเห็นกับคำตอบของ hesselbom (ชื่อเสียงไม่เพียงพอ) ดังนั้นฉันจึงเพิ่มของฉันเอง ...

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

สิ่งนี้ทำงานได้ดีที่สุดสำหรับฉันเพราะมันช่วยกำจัดช่องว่าง (วินาที \ s *) และท้ายหน้า (แรก \ s *) โดยอัตโนมัติและข้ามบรรทัดว่าง (ธง PREG_SPLIT_NO_EMPTY)

- = OPTIONS = -

หากคุณต้องการให้ช่องว่างนำหน้ากำจัดส่วนที่สอง \ s * และทำให้เป็น rtrim () แทน ...

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

หากคุณต้องการเก็บบรรทัดว่างไว้ให้กำจัด NULL (เป็นเพียงตัวยึดตำแหน่ง) และตั้งค่าสถานะ PREG_SPLIT_NO_EMPTY อย่างเช่น ...

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

หรือรักษาทั้งช่องว่างนำหน้าและบรรทัดว่าง ...

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

ฉันไม่เห็นเหตุผลใด ๆ ว่าทำไมคุณต้องการเก็บช่องว่างต่อท้ายดังนั้นฉันขอแนะนำให้ทิ้ง \ s * แรกไว้ที่นั่น แต่ถ้าทุกสิ่งที่คุณต้องการคือการแยกบรรทัดใหม่ (ตามชื่อเรื่อง) มันเป็นเรื่องง่าย (ตามที่ Jan Goyvaerts) กล่าวถึง ...

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

mปรับปรุงไม่จำเป็นจริงๆมันคืออะไร? ไม่ส่งผลกระทบต่อ^และเท่านั้น$?
mpen

@mpen ใช่ฉันเชื่อว่าคุณถูกต้อง ฉันเพิ่งพกมันไปพร้อมกับเวอร์ชั่นของ hesselbom ฉันจะแก้ไขโพสต์ของฉัน
Deen Foxx

7
<anti-answer>

ตามที่ระบุไว้คำตอบอื่น ๆ ให้แน่ใจว่าได้ใช้explodeมากกว่าsplitเพราะเป็น PHP 5.3.0 splitเลิกใช้แล้ว เช่นสิ่งต่อไปนี้ไม่ใช่วิธีที่คุณต้องการ:

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

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

</anti-answer>

3

สำหรับทุกคนที่พยายามแสดง cronjobs ใน crontab และรู้สึกหงุดหงิดกับการแยกแต่ละบรรทัดให้ใช้ explode:

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

การใช้ '\ n' ดูเหมือนจะไม่ทำงาน แต่ chr (10) ทำงานได้ดี: D

หวังว่านี่จะช่วยบรรเทาอาการปวดหัวได้บ้าง


สวัสดี Jeff ยินดีต้อนรับสู่ SO คุณควรเขียนสิ่งนี้เป็นคำถามและคำตอบแทนที่จะตอบคำถามของคนอื่น นี่คือเว็บไซต์ถามตอบไม่ใช่ฟอรัมทั่วไป ดูคำถามที่พบบ่อย - stackoverflow.com/faq
Rebecca Scott

การใช้'\n'ไม่ทำงานเนื่องจากเอสเคปลำดับไม่ได้ถูกตีความในเครื่องหมายคำพูดเดี่ยวคุณต้องใช้เครื่องหมายคำพูดแทน: "\n"แทนที่จะ'n'อ่านphp.net/manual/en/language.types.string.php
Christopher K.


2

คุณสามารถทำ $ string = nl2br ($ string) เพื่อให้ตัวแบ่งบรรทัดของคุณเปลี่ยนเป็น

<br />. 

วิธีนี้ไม่สำคัญว่าระบบจะใช้ \ r \ n หรือ \ n หรือ \ r

จากนั้นคุณสามารถป้อนลงในอาร์เรย์:

$array = explode("<br />", $string);

หมายเหตุ: nl2brไม่ได้แทนที่ตัวแบ่งบรรทัด ... มันจะแทรกเฉพาะแท็กเบรกก่อนการขึ้นบรรทัดใหม่แต่ละครั้ง ดังนั้นรายการอาเรย์ทั้งหมดของคุณที่นอกเหนือจากตอนแรกจะเริ่มต้นด้วยการขึ้นบรรทัดใหม่ หากวิธีนี้ไม่สำคัญสำหรับคุณวิธีนี้จะเร็วที่สุด หากเป็นเช่นนั้นคำตอบของจาคาร์ก็เร็วที่สุด
Aust

2

นั่นคือทางของฉัน:

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

สิ่งนี้จะข้ามบรรทัดว่างทั้งหมดด้วย


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

อาร์เรย์ที่แท้จริง:

$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

ฝังออนไลน์:

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


เพิ่มคำอธิบายพร้อมคำตอบสำหรับวิธีที่คำตอบนี้ช่วย OP ในการแก้ไขปัญหาปัจจุบัน
Kяσѕρєя K

1

เลือกสิ่งนี้ใน php docs:

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

0

วิธีนี้ใช้ได้ผลกับฉันเสมอ:

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

1
รักการสบถเป็นส่วนหนึ่งของรหัส :) อย่างไรก็ตามการแทนที่ด้วย \ n นั้นง่ายกว่าและปลอดภัยกว่า (ดูคำตอบอื่น ๆ )
Stefan Reich

0

การใช้แพ็คเกจ 'ฐาน' เท่านั้นเป็นวิธีแก้ปัญหาสำหรับกรณีง่าย ๆ :

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

-6

การใช้อักขระพิเศษใด ๆ ระหว่างสตริงหรือตัวแบ่งบรรทัด\nโดยใช้ PHP explode เราสามารถทำได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.