ฉันจะระเบิดและตัดช่องว่างได้อย่างไร


167

ตัวอย่างเช่นฉันต้องการสร้างอาร์เรย์จากองค์ประกอบในสตริงนี้:

$str = 'red,     green,     blue ,orange';

ฉันรู้ว่าคุณสามารถระเบิดและวนรอบพวกเขาและตัดแต่ง:

$arr = explode(',', $str);
foreach ($arr as $value) {
    $new_arr[] = trim($value);
}

แต่ฉันรู้สึกเหมือนมีวิธีการหนึ่งบรรทัดที่สามารถจัดการกับสิ่งนี้ได้ ความคิดใด ๆ

คำตอบ:


449

คุณสามารถทำสิ่งต่อไปนี้โดยใช้array_map :

$new_arr = array_map('trim', explode(',', $str));

10
นี่คือการวนซ้ำ (ภายใน) โดย PHP
Jason OOO

2
นี้ .... บันทึกไว้ .... ชีวิตของฉัน .... ฉันพยายามจัดการไฟล์ผ่าน fseek เพื่อต่อท้ายไฟล์ ... เมื่อฉันตัดสินใจที่จะทำลายมันลงในอาร์เรย์และเขียนใหม่ ไฟล์ฉันเห็นว่ามีการเพิ่มช่องว่างพิเศษตลอดเวลา ... นี่ + implode ช่วยชีวิตฉันไว้ ... ฉันไปกินอาหารได้แล้ว
jenki221

4
@ JasonOOO ฉันคิดว่าในความเห็นของคนส่วนใหญ่สองสามมิลลิวินาที (ถ้าเป็นอย่างนั้น) เป็นการแลกเปลี่ยนที่ยุติธรรมสำหรับการมีโค้ดที่สั้นง่ายและอ่านง่าย
Gavin

ง่ายและเข้าใจง่าย อย่างไรก็ตามหากจัดการกับชุดข้อมูลขนาดใหญ่คำตอบที่มีประสิทธิภาพยิ่งขึ้นให้โดย @ amr-eladwy เป็นทางออกที่ดีกว่า
Yaron

ฉันชอบโค้ดนี้แล้วกลับมาที่ไซต์นี้อีกครั้งแล้ว!
patrickzzz

52

คำตอบที่ดีขึ้น

preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange');

ผลลัพธ์:

Array
(
    [0] => red
    [1] => green thing
    [2] => blue
    [3] => orange
)

นี้

  • แยกเครื่องหมายจุลภาคเท่านั้น
  • ตัดแต่งช่องว่างสีขาวจากแต่ละรายการ
  • ละเว้นรายการที่ว่างเปล่า
  • ไม่แยกรายการด้วยช่องว่างภายในเช่น "สิ่งที่เป็นสีเขียว"

7
ใครสามารถอธิบายได้ว่าทำไมคำตอบนี้ไม่มี 100 upvotes Regexp นั้นยากที่จะเข้าใจ แต่มันแจงไฟล์ของฉันที่ 100Mb เร็วกว่าโซลูชันอื่น ๆ
Dan Dan

2
ฉันดีใจที่คุณพบว่ามีประโยชน์ ฉันอ่านคำตอบทั้งหมดและมาพร้อมกับการผสมผสานที่ดีกว่า regex สามารถอธิบายได้ในรายละเอียด
Amr ElAdawy

2
ขออภัย regex นี้เป็นสิ่งที่ผิด - ลองเปลี่ยนด้วยred *red*สิ่งที่ดีกว่าอาจเป็น / (\ s *, \ s *) + /
เกร็ก

@AmrElAdawy FYI สิ่งนี้ไม่ทำงานอีกต่อไปหลังจากการอัปเดต 8/28 ด้วย regex ในคำตอบตามที่เป็นอยู่พื้นที่สีขาวไม่ได้ถูกตัดแต่งจากองค์ประกอบบางอย่าง ตัวอย่าง: 'สิ่งที่เป็นสีเขียว'
Samsquanch

1
@Samsquanch อัปเดตแล้ว โปรดแจ้งให้เราทราบหากคุณพบปัญหาใด ๆ
Amr ElAdawy

25

ต่อไปนี้จะดูแลช่องว่างสีขาวที่จุดเริ่มต้น / สิ้นสุดของสตริงอินพุต:

$new_arr = preg_split('/\s*,\s*/', trim($str));

และนี่คือการทดสอบขั้นต่ำพร้อมช่องว่างสีขาวในทุกตำแหน่งที่เหมาะสม:

$str = ' first , second , third , fourth, fifth ';
$new_arr = preg_split('/\s*,\s*/', trim($str));
var_export($str);

ตั้งแต่array_mapและโซลูชัน regexp ให้ผลลัพธ์ที่เหมือนกันทุกคนสามารถเปรียบเทียบประสิทธิภาพได้หรือไม่
ด่าน

@ แดนสำหรับกรณีเช่นนี้มันจะไม่แตกต่างกัน
Aris

4

นี่เป็นวิธีที่คุณแทนที่และระเบิดในรหัสบรรทัดเดียว

$str = 'red,     green,     blue ,orange';

$new_string = explode(',',preg_replace('/\s+/', '', $str));

จะแสดงผลลัพธ์เป็น

Array
(
    [0] => red
    [1] => green
    [2] => blue
    [3] => orange
)

3

ด้วยการรวมหลักการบางอย่างในคำตอบที่มีอยู่ฉันจึงคิดขึ้นมา

preg_split ('/\s*,+\s*/', 'red,     green thing ,,  ,,   blue ,orange', NULL, PREG_SPLIT_NO_EMPTY);

เหตุผลที่อยู่เบื้องหลังคือฉันพบข้อบกพร่องในคำตอบนี้ถ้ามีเครื่องหมายจุลภาคที่ท้ายสตริงมันจะส่งคืนองค์ประกอบว่างในอาร์เรย์ กล่าวคือ

preg_split ('/(\s*,*\s*)*,+(\s*,*\s*)*/', 'red,     green thing ,,  ,,   blue ,orange,');

ผลลัพธ์ใน

Array
(
  [0] => red
  [1] => green thing
  [2] => blue
  [3] => orange
  [4] => ''
)

คุณสามารถแก้ไขได้โดยใช้PREG_SPLIT_NO_EMPTYดังที่ได้กล่าวไว้ในคำตอบนี้เพื่อลบออก แต่เมื่อคุณทำเช่นนั้นแล้วในทางเทคนิคแล้วไม่จำเป็นต้องลบเครื่องหมายจุลภาคต่อเนื่องกันผ่าน Regex ดังนั้นการแสดงออกที่สั้นลง


2

คุณสามารถทำได้ด้วย regex หนึ่งบรรทัด

preg_split('@(?:\s*,\s*|^\s*|\s*$)@', $str, NULL, PREG_SPLIT_NO_EMPTY);

1

ลองนี้:

$str = preg_replace("/\s*,\s*/", ",", 'red,     green,     blue ,orange');

OP ต้องการอาร์เรย์ preg_replace()ไม่ได้สร้างอาร์เรย์จากสตริง นี่คือคำตอบที่ถูกสำหรับคำถามที่ผิด downvoted
mickmackusa

1
$list = preg_split("/\s*,\s*/", 'red, green, blue ,orange');การปรับเปลี่ยนเล็กน้อยจะช่วยฟื้นฟูคำตอบ
dreftymac

1

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

รหัส: ( สาธิต )

$str = ' red,     green,     blue ,orange ';
var_export(str_word_count($str,1));  // 1 means return all words in an indexed array

เอาท์พุท:

array (
  0 => 'red',
  1 => 'green',
  2 => 'blue',
  3 => 'orange',
)

นอกจากนี้ยังสามารถปรับให้เหมาะกับวัสดุพิมพ์ที่เกินตัวอักษร (และเครื่องหมายยัติภังค์และเครื่องหมายอัญประกาศ - หากคุณอ่านงานพิมพ์ละเอียด) โดยการเพิ่มอักขระที่จำเป็นลงในพารามิเตอร์ mask mask / 3rd

รหัส: ( สาธิต )

$str = " , Number1 ,     234,     0 ,4heaven's-sake  ,  ";
var_export(str_word_count($str,1,'0..9'));

เอาท์พุท:

array (
  0 => 'Number1',
  1 => '234',
  2 => '0',
  3 => '4heaven\'s-sake',
)

อีกครั้งฉันปฏิบัติต่อคำถามนี้อย่างหวุดหวิดเนื่องจากสตริงตัวอย่าง แต่สิ่งนี้จะให้ผลลัพธ์ที่ต้องการเหมือนกัน:

รหัส: ( สาธิต )

$str = ' red,     green,     blue ,orange ';
var_export(preg_match_all('/[^, ]+/',$str,$out)?$out[0]:'fail');

0

คุณสามารถใช้preg_split ()สำหรับสิ่งนั้นได้

$bar = preg_split ('/[,\s]+/', $str);
print_r ($bar);

/* Result:
  Array
  (
      [0] => red
      [1] => green
      [2] => blue
      [3] => orange
  )
 */

ที่จะแยกช่องว่างในองค์ประกอบของคุณ
Chris KL

ย้ายเครื่องหมายจุลภาคไปทางซ้ายของเครื่องหมายวงเล็บสี่เหลี่ยมเพื่อให้ต้องใช้เครื่องหมายจุลภาค
Eric Leschinski

การย้ายเครื่องหมายจุลภาคไปทางซ้ายจะไม่สามารถแก้ไขได้ โปรดตรวจสอบคำตอบของฉันด้านล่างstackoverflow.com/a/38300330/5079380
Amr ElAdawy

-4
$str = str_replace(" ","", $str);

4
Trim ทำมากกว่านี้ ... มันจดจ้อง\t\n\r\0\x0Bด้วย
Arian Faurtosh

3
ไม่เพียงแค่นั้น แต่สิ่งนี้จะทำให้องค์ประกอบมีพื้นที่ว่างมากขึ้น
Adam Kiss

-11

ตัดแต่งและระเบิด

$ str = 'แดง, เขียว, น้ำเงิน, ส้ม';

$ str = trim ($ str);

$ strArray = explode (',', $ str);

print_r ($ strArray);


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