146

有没有一种很好的方法来迭代字符串的字符?我希望能够对字符串的字符执行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)一种从字符串构建字符数组的更好方法(如果是这样,另一个方向如何?)

我觉得我在这里错过了一些明显的东西。

4

9 回答 9

216

步骤 1:str_split使用函数将字符串转换为数组

$array = str_split($your_string);

第 2 步:循环遍历新创建的数组

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

您可以查看 PHP 文档以获取更多信息:str_split

于 2011-01-05T05:20:57.053 回答
113

迭代字符串:

for ($i = 0; $i < strlen($str); $i++){
    echo $str[$i];
}
于 2016-10-24T09:30:17.290 回答
21

如果你的字符串是 Unicode,你应该使用preg_splitwith/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 ); 
} 
于 2012-01-08T18:28:53.737 回答
13

如果您只需要访问它,您也可以像访问数组一样访问 $s1:

$s1 = "hello world";
echo $s1[0]; // -> h
于 2016-02-18T21:47:20.303 回答
7

对于那些正在寻找在 php 中迭代字符串的最快方法的人,我准备了一个基准测试。
第一种直接访问字符串字符的方法,方法是在括号中指定其位置并将字符串视为数组:

$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

这意味着第二种方法更快。

于 2016-09-02T07:36:52.820 回答
6

从@SeaBrightSystems 答案扩展,你可以试试这个:

$s1 = "textasstringwoohoo";
$arr = str_split($s1); //$arr now has character array
于 2015-05-15T07:55:14.087 回答
4

嗯……没必要把事情复杂化。基础知识总是很好。

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

前进方向:

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

输出:abcdef

反向:

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

输出:fedcba

于 2018-12-21T06:19:56.517 回答
4

大多数答案都忘记了非英文字符!

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) "ث"
于 2019-09-01T17:15:39.643 回答
3
// 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;
}
于 2016-08-29T05:04:53.297 回答