PHP-迭代字符串字符

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

我觉得我漏掉了一些明显的东西。

201145 次浏览

使用 Str _ split迭代 ASCII 字符串(从 PHP 5.0开始)

如果字符串包含 只有 ASCII (即“ English”)字符,则使用 Str _ split

$str = 'some text';
foreach (str_split($str) as $char) {
var_dump($char);
}

使用 Mb _ str _ split迭代 Unicode 字符串(从 PHP 7.4开始)

如果字符串 也许吧包含 Unicode (即“非英语”)字符,则必须使用 Mb _ str _ split

$str = 'μυρτιὲς δὲν θὰ βρῶ';
foreach (mb_str_split($str) as $char) {
var_dump($char);
}

如果字符串使用 Unicode,则应使用带有 /u修饰符的 preg_split

来自 php 文档中的评论:

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

扩展自@SeaBrightSystems 的回答,你可以试试这个:

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

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

$s1 = "hello world";
echo $s1[0]; // -> h
// 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;
}

对于那些正在寻找在 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倍,就会得到这些基准测试结果:

使用 string [ i ]
0.24960017204285 Seconds

使用 str _ split
0.18720006942749 Seconds

也就是说第二种方法更快。

迭代字符串:

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

嗯... 没有必要把事情复杂化。基本的东西总是很好用。

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

前进方向:

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

输出: abcdef

反方向:

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

输出: fedcba

大多数的答案忘记了非英语字符! ! !

strlen计算的是字节数,而不是字符数,这就是为什么它和它的兄弟函数可以很好地处理英文字符,因为英文字符在 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) "ث"