<?php
$subject = "any";
$b = " ";
$delimited = "$b$subject$b";
$replace = array("?","*","(",")",",",".");
$str = "Will *any* company do *any* job, (are there any)?";
echo "\nThe string: \"$str\"";
$temp = str_replace($replace,$b,$str);
while ( ($pos = strpos($temp,$delimited)) !== false )
{
echo "\nThe subject \"$subject\" occurs at position ",($pos + 1);
for ($i=0,$max=$pos + 1 + strlen($subject); $i <= $max; $i++) {
$temp[$i] = $b;
}
}
См. демонстрацию
Сценарий определяет границу слова как пробел. Если в строке есть неалфавитные символы, они заменяются пробелом, а результат сохраняется в $temp
. По мере повторения цикла и обнаружения $subject
каждый из его символов превращается в пробел, чтобы найти следующее появление субъекта. Учитывая объем проделанной работы, можно задаться вопросом, действительно ли такие усилия окупаются по сравнению с использованием регулярного выражения с функцией preg_. Это то, что каждый должен будет решить сам. Моя цель состояла в том, чтобы показать, как этого можно достичь с помощью strpos(), не прибегая к часто повторяемому общепринятому мнению SO, которое выступает за использование регулярных выражений.
Существует вариант, если вы ненавидите создавать замещающий массив неалфавитных символов следующим образом:
<?php
function getAllWholeWordPos($s,$word){
$b = " ";
$delimited = "$b$word$b";
$retval = false;
for ($i=0, $max = strlen( $s ); $i < $max; $i++) {
if ( !ctype_alpha( $s[$i] ) ){
$s[$i] = $b;
}
}
while ( ( $pos = stripos( $s, $delimited) ) !== false ) {
$retval[] = $pos + 1;
for ( $i=0, $max = $pos + 1 + strlen( $word ); $i <= $max; $i++) {
$s[$i] = $b;
}
}
return $retval;
}
$whole_word = "any";
$str = "Will *$whole_word* company do *$whole_word* job, (are there $whole_word)?";
echo "\nString: \"$str\"";
$result = getAllWholeWordPos( $str, $whole_word );
$times = count( $result );
echo "\n\nThe word \"$whole_word\" occurs $times times:\n";
foreach ($result as $pos) {
echo "\nPosition: ",$pos;
}
См. демонстрацию
Обратите внимание, что этот пример с его обновлением улучшает код, предоставляя функцию, которая использует вариант strpos(), а именно stripos(), который имеет дополнительное преимущество, заключающееся в том, что он нечувствителен к регистру. Несмотря на более трудоемкое кодирование, производительность высокая; см. производительность.
person
slevy1
schedule
13.06.2017
strpos()
будет всегда определять позицию введенной вами строки. Если это не то, что вы хотите, не используйте его. - person billynoah   schedule 14.06.2017strpos
и хотите использовать толькоany
как отдельное слово, просто используйте пробел до и после слова и добавьте единицу к результирующему индексу. - person fubar   schedule 14.06.2017strpos()
и (вероятно) мог бы повысить производительность, просто используя регулярное выражение. Для меня этот вопрос похож на вопрос: как я могу использовать оператор==
для строгого сравнения, потому что == работает лучше, чем === - person billynoah   schedule 14.06.2017strpos()
, которая устраняет необходимость в регулярном выражении. Это 100% ответ. И в самом деле было весело, как мысленный эксперимент. - person Jared Farrish   schedule 14.06.2017'/\bany\b/'
код работает значительно медленнее 3v4l.org/SXAau/perf#output . Имея это в виду, я думаю, если вы действительно хотите сосредоточиться на производительности, вам нужно смотреть на каждую часть в отдельности. - person Andreas   schedule 14.06.2017preg_match_all()
, чтобы посмотреть, как они выступили. сравнение, по общему признанию, немного несправедливо, поскольку функция Джареда возвращает только первую позицию, в то время как две другие получают все совпадения и позиции. Результаты для 1 миллиона итераций каждого из них были следующими:firstWordPosition()
заняло 1,067 секунды, ответ slevy: 8,977 секунды,preg_match_all()
0,905 секунды. - person billynoah   schedule 19.06.2017