PHP-문자열 문자 반복


120

문자열의 문자를 반복하는 좋은 방법이 있습니까? 나는 할 수 있도록하고 싶습니다 foreach, array_map, array_walk, array_filter문자열의 문자에 등.

타입 캐스팅 / 저글링은 저를 어디에도 가지지 못했습니다 (전체 문자열을 배열의 한 요소로 넣음). 내가 찾은 최고의 솔루션은 단순히 for 루프를 사용하여 배열을 구성하는 것입니다. 더 나은 것이 있어야 할 것 같습니다. 색인을 생성 할 수 있다면 반복 할 수 없어야하지 않나요?

이것은 내가 가진 최고입니다

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 2011 년

1
여기에는 실제 목표가 없습니다. 내가 가지고 놀던 호기심 이었어. 문자열에 대한 색인을 생성 할 수 있지만 반복 할 수 없다는 것이 이상해 보였습니다. 난 의미 예를 들어, 사용을 생각하는 손실에, 그러나 어떤 방법이 명시 적으로 문자 배열을 구성하지 않고 문자열의 문자 반복이 있다면 난 여전히 알고 싶다
jon_darkstar

그래도 좋은 점은 분명히 내 예제는 꽤 얕습니다. 즉 - 당신이 할 거라고 주로 어떤 array_filter의미에서 더 나은 문자열이나 REG-전 기능을 수행 할 수 있습니다
jon_darkstar

projecteuler.net/problem=20을 해결 하는 것이 (다소 인위적이지만) 사용 사례가 될 수 있습니다.
Nick Edwards

for ($ 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 귀하의 응용 프로그램을 모르지만 배열의 각 항목에는 상당한 오버 헤드 (4 바이트 IIRC)가 있다는 점에 유의하십시오. 건너 뛰어
Daan Timmer

str_split() will split into bytes, rather than characters when dealing with a multi-byte encoded string.- str_split유니 코드로 작업 할 수 없음
Happy

85

반복 문자열 :

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

7
이것은 '배열로 변환'과는 반대로 문자열을 반복하는 방법과 같은 질문에 답하기 때문에 더 나은 대답처럼 보입니다.
Robin Andrews

2
LOL !!!!! 모든 @OmarTariq. 이것은 제공된 답변보다 훨씬 효율적입니다.
0x476f72616e

5
strlen()각 반복에 대해 호출 하고 있다는 점에 유의하십시오 . PHP는 길이가 미리 계산되어 있기 때문에 끔찍한 일은 아니지만 여전히 함수 호출입니다. 속도가 필요한 경우 루프를 시작하기 전에 변수에 저장하는 것이 좋습니다.
Vilx-

2
이것은 멀티 바이트 문자열에는 좋지 않습니다. 왜냐하면 여기서 우리는 심볼이 아닌 바이트 오프셋을 얻고 있기 때문입니다
항상

2
@OmarTariq "이것이 답입니다. 세상에 무슨 문제가 있습니까?" .... 세상의 잘못된 점은 세상에 영어가 아닌 다른 언어가 있다는 것입니다.이 함수는 항상 말했듯이 문자가 아닌 문자열의 바이트를 반복합니다.
회계사 م

20

문자열이 유니 코드 인 경우 수정 자 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에 액세스 할 수도 있습니다.

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

6

@SeaBrightSystems 답변에서 확장하면 다음을 시도해 볼 수 있습니다.

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

동의하지 않습니다.이 답변은 가치를 추가하며 str_split이 PHP 응용 프로그램에서 작동하는 방법에 대한 작업 예를 제공합니다. @SeaBrightSystems는 문서에 대한 링크 일 뿐이며, 예를 들어 사용자가 함수가 어떻게 작동하는지 확인하려고 할 때 도움이되지 않는 경우가 있습니다. 그렇지 않으면 대부분의 답변은 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시간 에 대해 위의 각 메서드의 마지막 줄을 호출하면 다음과 같은 벤치마킹 결과가 나타납니다.

string [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 개의 찬성표를 얻었다는 것에 놀랐습니다 :( 이것은 가장 / 유일하게 신뢰할 수있는 답변입니다
Accountant م

1

대부분의 답변은 영어가 아닌 문자를 잊어 버렸습니다 !!!

strlen문자가 아닌 BYTES를 계산합니다. 그렇기 때문에 형제 함수는 영어 문자와 잘 작동합니다. 영어 문자는 UTF-8 및 ASCII 인코딩 모두에서 1 바이트로 저장되므로 멀티 바이트 문자열 함수 를 사용해야합니다. 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.