PHP - วนซ้ำอักขระสตริง


121

มีวิธีที่ดีในการย้ำอักขระของสตริงหรือไม่? ฉันต้องการที่จะสามารถที่จะทำforeach, array_map, array_walk, array_filterฯลฯ ในตัวละครของสตริง

ประเภทการคัดเลือกนักแสดง / การเล่นกลไม่ได้ทำให้ฉันไปไหน (ใส่สตริงทั้งหมดเป็นองค์ประกอบเดียวของอาร์เรย์) และทางออกที่ดีที่สุดที่ฉันพบคือใช้ for loop เพื่อสร้างอาร์เรย์ รู้สึกว่าน่าจะมีอะไรดีกว่านี้ ฉันหมายความว่าถ้าคุณสามารถสร้างดัชนีได้คุณก็ไม่สามารถทำซ้ำได้เช่นกัน?

นี่คือสิ่งที่ดีที่สุดที่ฉันมี

function stringToArray($s)
{
    $r = array();
    for($i=0; $i<strlen($s); $i++) 
         $r[$i] = $s[$i];
    return $r;
}

$s1 = "textasstringwoohoo";
$arr = stringToArray($s1); //$arr now has character array

$ascval = array_map('ord', $arr);  //so i can do stuff like this
$foreach ($arr as $curChar) {....}
$evenAsciiOnly = array_filter( function($x) {return ord($x) % 2 === 0;}, $arr);

มีทั้ง:

A) วิธีทำให้สตริงซ้ำได้
B) วิธีที่ดีกว่าในการสร้างอาร์เรย์อักขระจากสตริง (ถ้าเป็นเช่นนั้นจะเป็นอย่างไรในทิศทางอื่น?)

ฉันรู้สึกเหมือนขาดอะไรบางอย่างที่เห็นได้ชัดที่นี่


บางทีคุณควรพูดเพิ่มเติมเกี่ยวกับสิ่งที่คุณกำลังพยายามทำให้สำเร็จ ... ดูเหมือนว่าอาจมีวิธีที่ดีกว่าในการใช้การดำเนินการสตริงปกติ
Vinay Pai

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

นั่นเป็นจุดที่ดีเห็นได้ชัดว่าตัวอย่างของฉันค่อนข้างตื้น กล่าวคือ - ส่วนใหญ่สิ่งที่คุณทำarray_filterในแง่นี้สามารถทำได้ดีกว่าด้วยฟังก์ชัน string หรือ reg-ex
jon_darkstar

การแก้projecteuler.net/problem=20อาจเป็นตัวอย่างการใช้งาน (แม้ว่าจะมีการสร้างไว้บ้าง)
Nick Edwards

หมายเหตุหนึ่งเกี่ยวกับ ($ i = 0; $ i <strlen ($ s); $ i ++) ฉันจะเก็บ strlen ($ s) ไว้ในตัวแปรก่อนที่จะวนซ้ำด้วยวิธีนี้คุณจะไม่เรียก strlen () มากกว่า 1 ครั้ง
Amin

คำตอบ:


176

ขั้นตอนที่ 1:แปลงสตริงเป็นอาร์เรย์โดยใช้str_splitฟังก์ชัน

$array = str_split($your_string);

ขั้นตอนที่ 2:วนซ้ำอาร์เรย์ที่สร้างขึ้นใหม่

foreach ($array as $char) {
 echo $char;
}

คุณสามารถตรวจสอบเอกสาร PHP สำหรับข้อมูลเพิ่มเติม: str_split


ฮะว้าว. ใช่นั่นมัน และแน่นอนว่าการระเบิดสามารถทำในทิศทางอื่นได้ ฉันจะยอมรับสิ่งนี้เร็ว ๆ นี้เว้นแต่จะมีใครสามารถแสดงวิธีทำซ้ำได้อย่างถูกต้อง
jon_darkstar

@jon_darkstar ฉันไม่รู้จักแอปพลิเคชันของคุณ แต่โปรดทราบว่าแต่ละรายการในอาร์เรย์มีค่าโสหุ้ยที่สำคัญ (4bytes IIRC) ข้ามไปเลยมันเป็นวิธีที่ 'ค่อนข้าง' มากกว่า: nikic.github.com/2011/12/12/…
Daan Timmer

str_split() will split into bytes, rather than characters when dealing with a multi-byte encoded string.- str_splitไม่สามารถทำงานกับ Unicode ได้
สุขสันต์

86

ย้ำสตริง:

for ($i = 0; $i < strlen($str); $i++){
    echo $str[$i];
}

7
ดูเหมือนว่าจะเป็นคำตอบที่ดีกว่าเพราะตอบคำถามนั่นคือวิธีการวนซ้ำบนสตริงซึ่งต่างจาก 'แปลงเป็นอาร์เรย์'
Robin Andrews

2
ฮ่า ๆ!!!!! ทุกอย่าง @OmarTariq. สิ่งนี้มีประสิทธิภาพมากกว่าคำตอบที่ให้ไว้มาก
0x476f72616e

5
โปรดทราบว่าคุณกำลังเรียกร้องให้strlen()ทำซ้ำแต่ละครั้ง ไม่ใช่เรื่องน่ากลัวเนื่องจาก PHP มีการคำนวณความยาวล่วงหน้า แต่ยังคงเป็นการเรียกใช้ฟังก์ชัน หากคุณต้องการความเร็วให้บันทึกในตัวแปรก่อนที่จะเริ่มลูป
Vilx-

2
นี้ไม่ดีสำหรับสตริง multibyte เพราะที่นี่เรากำลัง Gettings ไบต์ชดเชยไม่ได้เป็นสัญลักษณ์
alvery

2
@OmarTariq "นี่คือคำตอบโลกผิดอะไร" .... ผิดกับโลกคือโลกนี้มีภาษาอื่นที่ไม่ใช่ภาษาอังกฤษฟังก์ชันนี้ตามที่อัลเวอรี่กล่าวว่าจะวนซ้ำไบต์ในสตริงไม่ใช่อักขระ
Accountant

20

หากสตริงของคุณอยู่ใน Unicode คุณควรใช้preg_splitกับ/uตัวปรับแต่ง

จากความคิดเห็นในเอกสาร php:

function mb_str_split( $string ) { 
    # Split at all position not after the start: ^ 
    # and not before the end: $ 
    return preg_split('/(?<!^)(?!$)/u', $string ); 
} 

1
สำหรับสตริงหลายไบต์mb_splitมีความน่าเชื่อถือมากกว่า
Élektra

12

คุณยังสามารถเข้าถึง $ s1 เช่นอาร์เรย์ได้หากคุณต้องการเข้าถึงเท่านั้น:

$s1 = "hello world";
echo $s1[0]; // -> h

6

ขยายจากคำตอบของ @SeaBrightSystems คุณสามารถลองสิ่งนี้:

$s1 = "textasstringwoohoo";
$arr = str_split($s1); //$arr now has character array

ฉันไม่เห็นด้วยคำตอบนี้เพิ่มมูลค่ามันให้ตัวอย่างการทำงานว่า str_split อาจทำงานอย่างไรในแอปพลิเคชัน PHP @SeaBrightSystems เพียงแค่เชื่อมโยงไปยังเอกสารซึ่งบางครั้งก็ไม่เป็นประโยชน์เมื่อมีคนพยายามดูว่าฟังก์ชันอาจทำงานอย่างไรตามตัวอย่าง มิฉะนั้นคำตอบ SO ส่วนใหญ่จะเป็นลิงก์ไปยัง php.net
kurdtpage

6

สำหรับผู้ที่กำลังมองหาวิธีที่เร็วที่สุดในการทำซ้ำสตริงใน php Ive ได้เตรียมการทดสอบมาตรฐาน
วิธีแรกที่คุณเข้าถึงอักขระสตริงโดยตรงโดยระบุตำแหน่งในวงเล็บและปฏิบัติต่อสตริงเช่นอาร์เรย์:

$string = "a sample string for testing";
$char = $string[4] // equals to m

ฉันคิดว่าวิธีหลังเป็นวิธีที่เร็วที่สุด แต่ฉันคิดผิด
เช่นเดียวกับวิธีที่สอง (ซึ่งใช้ในคำตอบที่ยอมรับ):

$string = "a sample string for testing";
$string = str_split($string);
$char = $string[4] // equals to m

วิธีนี้จะเร็วขึ้นเนื่องจากเราใช้อาร์เรย์จริงและไม่ได้สมมติว่าหนึ่งเป็นอาร์เรย์

การเรียกบรรทัดสุดท้ายของแต่ละวิธีข้างต้นเป็น1000000เวลานำไปสู่ผลลัพธ์การเปรียบเทียบเหล่านี้:

การใช้สตริง [i]
0.24960017204285 Seconds

ใช้ str_split
0.18720006942749 Seconds

ซึ่งหมายความว่าวิธีที่สองจะเร็วกว่า


3

อืม ... ไม่ต้องซับซ้อนอะไรมากมาย พื้นฐานใช้งานได้ดีเสมอ

    $string = 'abcdef';
    $len = strlen( $string );
    $x = 0;

ทิศทางไปข้างหน้า:

while ( $len > $x ) echo $string[ $x++ ];

ขาออก: abcdef

ทิศทางย้อนกลับ:

while ( $len ) echo $string[ --$len ];

ขาออก: fedcba


2
// Unicode Codepoint Escape Syntax in PHP 7.0
$str = "cat!\u{1F431}";

// IIFE (Immediately Invoked Function Expression) in PHP 7.0
$gen = (function(string $str) {
    for ($i = 0, $len = mb_strlen($str); $i < $len; ++$i) {
        yield mb_substr($str, $i, 1);
    }
})($str);

var_dump(
    true === $gen instanceof Traversable,
    // PHP 7.1
    true === is_iterable($gen)
);

foreach ($gen as $char) {
    echo $char, PHP_EOL;
}

ฉันประหลาดใจที่คำตอบนี้ได้รับการโหวตเพียง 1 ครั้ง :( นี่เป็นคำตอบที่น่าเชื่อถือที่สุด / เดียวเท่านั้นที่นี่
นักบัญชีم

1

คำตอบส่วนใหญ่ลืมเกี่ยวกับตัวอักษรที่ไม่ใช่ภาษาอังกฤษ !!!

strlenนับ BYTES ไม่ใช่อักขระนั่นคือเหตุผลว่าทำไมจึงเป็นเช่นนั้นและฟังก์ชันพี่น้องทำงานได้ดีกับอักขระภาษาอังกฤษเนื่องจากอักขระภาษาอังกฤษถูกเก็บไว้ใน 1 ไบต์ทั้งในการเข้ารหัส UTF-8 และ ASCII คุณต้องใช้ฟังก์ชันสตริงหลายไบต์ mb_*

สิ่งนี้จะใช้ได้กับอักขระใด ๆ ที่เข้ารหัสUTF-8

// 8 characters in 12 bytes
$string = "abcdأبتث";

$charsCount = mb_strlen($string, 'UTF-8');
for($i = 0; $i < $charsCount; $i++){
    $char = mb_substr($string, $i, 1, 'UTF-8');
    var_dump($char);
}

เอาต์พุตนี้

string(1) "a"
string(1) "b"
string(1) "c"
string(1) "d"
string(2) "أ"
string(2) "ب"
string(2) "ت"
string(2) "ث"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.