PHP: How to Properly Use Strpos() to Find a Word i

2019-06-14 17:21发布

问题:

If one is experienced in PHP, then one knows how to find whole words in a string and their position using a regex and preg_match() or preg_match_all. But, if you're looking instead for a lighter solution, you may be tempted to try with strpos(). The question emerges as to how one can use this function without it detecting substrings contained in other words. For example, how to detect "any" but not those characters occurring in "company"?

Consider a string like the following:

"Will *any* company do *any* job, (are there any)?"

How would one apply strpos() to detect each appearance of "any" in the string? Real life often involves more than merely space delimited words. Unfortunately, this sentence didn't appear with the non-alphabetical characters when I originally posted.

回答1:

I think you could probably just remove all the whitespace characters you care about (e.g., what about hyphenations?) and test for " word ":

var_dump(firstWordPosition('Will company any do any job, (are there any)?', 'any'));
var_dump(firstWordPosition('Will *any* company do *any* job, (are there any)?', 'any'));

function firstWordPosition($str, $word) {
    // There are others, maybe also pass this in or array_merge() for more control.
    $nonchars = ["'",'"','.',',','!','?','(',')','^','$','#','\n','\r\n','\t',];
    // You could also do a strpos() with an if and another argument passed in.
    // Note that we're padding the $str to with spaces to match begin/end.
    $pos = stripos(str_replace($nonchars, ' ', " $str "), " $word ");

    // Have to account for the for-space on " $str ".
    return $pos ? $pos - 1: false;
}

Gives 12 (offset from 0)

https://3v4l.org/qh9Rb



回答2:

<?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;
    }
}

See demo

The script defines a word boundary as a blank space. If the string has non-alphabetical characters, they are replaced with blank space and the result is stored in $temp. As the loop iterates and detects $subject, each of its characters changes into a space in order to locate the next appearance of the subject. Considering the amount of work involved one may wonder if such effort really pays off compared to using a regex with a preg_ function. That is something that one will have to decide themselves. My purpose was to show how this may be achieved using strpos() without resorting to the oft repeated conventional wisdom of SO which advocates using a regex.

There is an option if you are loathe to create a replacement array of non-alphabetical characters, as follows:

<?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;
}

See demo

Note, this example with its update improves the code by providing a function which uses a variant of strpos(), namely stripos() which has the added benefit of being case insensitive. Despite the more labor-intensive coding, the performance is speedy; see performance.



回答3:

Try the following code

<!DOCTYPE html>
<html>
<body>

<?php
echo strpos("I love php, I love php     too!","php");
?> 

</body>
</html>


Output: 7