Итак, еще раз я практикую PHP. конкретно strpos()
в то время как цикл.
Проблема с кодом ниже в том, что strpos()
результаты в 0
в первом цикле, который дает false
привести к условию while, тем самым завершив цикл.
$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, потому что он не обеспечивает быстрого выхода, когда больше не найдено игл (он повторяет всю строку независимо) — это может стать более дорогостоящим за более длительный срок строки. Представьте, что у вас есть строка из 10000 символов и единственное вхождение иглы находится на первом символе — это будет означать выполнение 9999 дополнительных итеративных проверок на отсутствие полезного вывода. Правда в том, что я не делал никаких сравнительных тестов, это может не иметь большого значения.
Что касается вашего метода, вам просто нужно выполнить строгое сравнение результатов strpos()
так что php будет правильно различать false
и 0
результат. Для этого вам нужно только обернуть strpos()
объявление в скобках и запись сравнения для конкретного типа (!==false
).
Вот два других способа (не-регулярное выражение и регулярное выражение):
Код: (демонстрация)
$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 () имеет настройку, в которой он может возвращать смещения всех слов в строке — тогда вы можете вызвать функцию фильтрации, чтобы сохранить только нужные слова. Просто подумал, что я добавлю это предложение для будущих читателей; это не относится к этому вопросу.