strpos of 0 打破 while 循环
strpos of 0 breaking while loop
所以我再次练习 PHP。具体来说 strpos()
在 while 循环中。
下面代码的问题在于 strpos()
在第一个循环中导致 0
,这会在 while 条件下产生 false
结果,从而终止循环。
$string = 'orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find = 'o';
$offset = 0;
$length = strlen($find);
while ($string_pos = strpos($string, $find, $offset)) {
echo 'String '.$find.' found at position '.$string_pos.'.<br>';
$offset = $length + $string_pos;
}
我对这一切都很陌生,有人可以帮我解释一下并提供解决方案吗?我正在寻找它来循环所有事件。
如果你不想使用strpos()
:
<?php
$string = 'orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find = 'o';
for($i = 0; $i <= strlen($string)-1; $i++){
// we are checking with each index of the string here
if($string[$i] == $find){
echo 'String '.$find.' found at position '.$i.'.<br>';
}
}
?>
我不太喜欢 Jigar 的 "iterate every character" 回答,因为当找不到更多的针时,它不会提供快速退出(无论如何它都会迭代整个字符串)——这可以在更长的字符串中变得更昂贵。假设您有一个 10,000 个字符的字符串,并且唯一出现的针出现在第一个字符上——这意味着要进行 9999 次以上的迭代检查以确保没有可用的输出。事实是我没有做任何基准测试,这可能根本不是什么大问题。
至于你的方法,你只需要对strpos()
的结果进行严格比较,这样php就能正确区分false
和0
结果。为此,您只需将 strpos()
声明括在括号中并编写特定于类型的比较 (!==false
).
这里有另外两种方式(非正则表达式和正则表达式):
代码:(Demo)
$string='orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find='o';
$offset=0;
$length=strlen($find);
while(($string_pos=strpos($string,$find,$offset))!==false){ // just use a strict comparison
echo "String $find found at position $string_pos\n";
$offset=$length+$string_pos;
}
echo "\n";
var_export(preg_match_all('/o/',$string,$out,PREG_OFFSET_CAPTURE)?array_column($out[0],1):'no matches');
输出:
String o found at position 0
String o found at position 12
String o found at position 14
String o found at position 28
array (
0 => 0,
1 => 12,
2 => 14,
3 => 28,
)
对于您的情况,preg_match_all()
一切都太过分了。但是,如果您想计算多个不同的单词、整个单词或其他棘手的事情,它可能是正确的工具。
除此之外,根据搜索场景,str_word_count() 有一个设置,它可以 return 字符串中所有单词的偏移量——然后你可以调用过滤函数只保留你想要的词。只是想我会为未来的读者提出这个建议;它不适用于这个问题。
所以我再次练习 PHP。具体来说 strpos()
在 while 循环中。
下面代码的问题在于 strpos()
在第一个循环中导致 0
,这会在 while 条件下产生 false
结果,从而终止循环。
$string = 'orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find = 'o';
$offset = 0;
$length = strlen($find);
while ($string_pos = strpos($string, $find, $offset)) {
echo 'String '.$find.' found at position '.$string_pos.'.<br>';
$offset = $length + $string_pos;
}
我对这一切都很陌生,有人可以帮我解释一下并提供解决方案吗?我正在寻找它来循环所有事件。
如果你不想使用strpos()
:
<?php
$string = 'orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find = 'o';
for($i = 0; $i <= strlen($string)-1; $i++){
// we are checking with each index of the string here
if($string[$i] == $find){
echo 'String '.$find.' found at position '.$i.'.<br>';
}
}
?>
我不太喜欢 Jigar 的 "iterate every character" 回答,因为当找不到更多的针时,它不会提供快速退出(无论如何它都会迭代整个字符串)——这可以在更长的字符串中变得更昂贵。假设您有一个 10,000 个字符的字符串,并且唯一出现的针出现在第一个字符上——这意味着要进行 9999 次以上的迭代检查以确保没有可用的输出。事实是我没有做任何基准测试,这可能根本不是什么大问题。
至于你的方法,你只需要对strpos()
的结果进行严格比较,这样php就能正确区分false
和0
结果。为此,您只需将 strpos()
声明括在括号中并编写特定于类型的比较 (!==false
).
这里有另外两种方式(非正则表达式和正则表达式):
代码:(Demo)
$string='orem ipsum dolor sit amet, consectetur adipisicing elit.';
$find='o';
$offset=0;
$length=strlen($find);
while(($string_pos=strpos($string,$find,$offset))!==false){ // just use a strict comparison
echo "String $find found at position $string_pos\n";
$offset=$length+$string_pos;
}
echo "\n";
var_export(preg_match_all('/o/',$string,$out,PREG_OFFSET_CAPTURE)?array_column($out[0],1):'no matches');
输出:
String o found at position 0
String o found at position 12
String o found at position 14
String o found at position 28
array (
0 => 0,
1 => 12,
2 => 14,
3 => 28,
)
对于您的情况,preg_match_all()
一切都太过分了。但是,如果您想计算多个不同的单词、整个单词或其他棘手的事情,它可能是正确的工具。
除此之外,根据搜索场景,str_word_count() 有一个设置,它可以 return 字符串中所有单词的偏移量——然后你可以调用过滤函数只保留你想要的词。只是想我会为未来的读者提出这个建议;它不适用于这个问题。