Showing posts with label PHP strpos. Show all posts
Showing posts with label PHP strpos. Show all posts

Monday, 8 October 2018

How do I check if a string contains a specific word?

Answers


You can use the strpos() function which is used to find the occurrence of one string inside another one:
$a = 'How are you?';

if (strpos($a, 'are') !== false) {
    echo 'true';
}
Note that the use of !== false is deliberate; strpos() returns either the offset at which the needle string begins in the haystack string, or the boolean false if the needle isn't found. Since 0 is a valid offset and 0 is "falsey", we can't use simpler constructs like !strpos($a, 'are').



Use strpos function:
if (strpos($a, 'are') !== false)
    echo 'true';



While most of these answers will tell you if a substring appears in your string, that's usually not what you want if you're looking for a particular word, and not a substring.
What's the difference? Substrings can appear within other words:
  • The "are" at the beginning of "area"
  • The "are" at the end of "hare"
  • The "are" in the middle of "fares"
One way to mitigate this would be to use a regular expression coupled with word boundaries (\b):
function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}
This method doesn't have the same false positives noted above, but it does have some edge cases of its own. Word boundaries match on non-word characters (\W), which are going to be anything that isn't a-zA-Z0-9, or _. That means digits and underscores are going to be counted as word characters and scenarios like this will fail:
  • The "are" in "What _are_ you thinking?"
  • The "are" in "lol u dunno wut those are4?"
If you want anything more accurate than this, you'll have to start doing English language syntax parsing, and that's a pretty big can of worms (and assumes proper use of syntax, anyway, which isn't always a given).



Using strstr() or stristr() if your search should be case insensitive would be another option.



If you want to avoid the "falsey" and "truthy" problem, you can use substr_count:
if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}
It's a bit slower than strpos but it avoids the comparison problems.



Peer to SamGoody and Lego Stormtroopr comments.
If you are looking for a PHP algorithm to rank search results based on proximity/relevance of multiple words here comes a quick and easy way of generating search results with PHP only:
Issues with the other boolean search methods such as strpos()preg_match()strstr() or stristr()
  1. can't search for multiple words
  2. results are unranked
It sounds difficult but is surprisingly easy.
If we want to search for multiple words in a string the core problem is how we assign a weight to each one of them?
If we could weight the terms in a string based on how representative they are of the string as a whole, we could order our results by the ones that best match the query.
This is the idea of the vector space model, not far from how SQL full-text search works:
function get_corpus_index($corpus = array(), $separator=' ') {

    $dictionary = array();

    $doc_count = array();

    foreach($corpus as $doc_id => $doc) {

        $terms = explode($separator, $doc);

        $doc_count[$doc_id] = count($terms);

        // tf–idf, short for term frequency–inverse document frequency, 
        // according to wikipedia is a numerical statistic that is intended to reflect 
        // how important a word is to a document in a corpus

        foreach($terms as $term) {

            if(!isset($dictionary[$term])) {

                $dictionary[$term] = array('document_frequency' => 0, 'postings' => array());
            }
            if(!isset($dictionary[$term]['postings'][$doc_id])) {

                $dictionary[$term]['document_frequency']++;

                $dictionary[$term]['postings'][$doc_id] = array('term_frequency' => 0);
            }

            $dictionary[$term]['postings'][$doc_id]['term_frequency']++;
        }

        //from http://phpir.com/simple-search-the-vector-space-model/

    }

    return array('doc_count' => $doc_count, 'dictionary' => $dictionary);
}

function get_similar_documents($query='', $corpus=array(), $separator=' '){

    $similar_documents=array();

    if($query!=''&&!empty($corpus)){

        $words=explode($separator,$query);

        $corpus=get_corpus_index($corpus, $separator);

        $doc_count=count($corpus['doc_count']);

        foreach($words as $word) {

            if(isset($corpus['dictionary'][$word])){

                $entry = $corpus['dictionary'][$word];


                foreach($entry['postings'] as $doc_id => $posting) {

                    //get term frequency–inverse document frequency
                    $score=$posting['term_frequency'] * log($doc_count + 1 / $entry['document_frequency'] + 1, 2);

                    if(isset($similar_documents[$doc_id])){

                        $similar_documents[$doc_id]+=$score;

                    }
                    else{

                        $similar_documents[$doc_id]=$score;

                    }
                }
            }
        }

        // length normalise
        foreach($similar_documents as $doc_id => $score) {

            $similar_documents[$doc_id] = $score/$corpus['doc_count'][$doc_id];

        }

        // sort from  high to low

        arsort($similar_documents);

    }   

    return $similar_documents;
}
CASE 1
$query = 'are';

$corpus = array(
    1 => 'How are you?',
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';
RESULT
Array
(
    [1] => 0.52832083357372
)
CASE 2
$query = 'are';

$corpus = array(
    1 => 'how are you today?',
    2 => 'how do you do',
    3 => 'here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';
RESULTS
Array
(
    [1] => 0.54248125036058
    [3] => 0.21699250014423
)
CASE 3
$query = 'we are done';

$corpus = array(
    1 => 'how are you today?',
    2 => 'how do you do',
    3 => 'here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';
RESULTS
Array
(
    [3] => 0.6813781191217
    [1] => 0.54248125036058
)
There are plenty of improvements to be made but the model provides a way of getting good results from natural queries, which don't have boolean operators such as strpos()preg_match()strstr() or stristr().
NOTA BENE
Optionally eliminating redundancy prior to search the words
  • thereby reducing index size and resulting in less storage requirement
  • less disk I/O
  • faster indexing and a consequently faster search.
1. Normalisation
  • Convert all text to lower case
2. Stopword elimination
  • Eliminate words from the text which carry no real meaning (like 'and', 'or', 'the', 'for', etc.)
3. Dictionary substitution
  • Replace words with others which have an identical or similar meaning. (ex:replace instances of 'hungrily' and 'hungry' with 'hunger')
  • Further algorithmic measures (snowball) may be performed to further reduce words to their essential meaning.
  • The replacement of colour names with their hexadecimal equivalents
  • The reduction of numeric values by reducing precision are other ways of normalising the text.
RESOURCES



I'm a bit impressed that none of the answers here that used strposstrstr and similar functions mentioned Multibyte String Functions yet (2015-05-08).
Basically, if you're having trouble finding words with characters specific to some languages, such as German, French, Portuguese, Spanish, etc. (e.g.: Ã¤Ã©Ã´Ã§ÂºÃ±), you may want to precede the functions with mb_. Therefore, the accepted answer would use mb_strpos or mb_stripos (for case-insensitive matching) instead:
if (mb_strpos($a,'are') !== false) {
    echo 'true';
}
If you cannot guarantee that all your data is 100% in UTF-8, you may want to use the mb_ functions.



if (preg_match('are', $a)) {
   echo 'true';
}



You can use the strstr function:
$haystack = "I know programming";
$needle   = "know";
$flag = strstr($haystack, $needle);

if ($flag){

    echo "true";
}
Without using an inbuilt function:
$haystack  = "hello world";
$needle = "llo";

$i = $j = 0;

while (isset($needle[$i])) {
    while (isset($haystack[$j]) && ($needle[$i] != $haystack[$j])) {
        $j++;
        $i = 0;
    }
    if (!isset($haystack[$j])) {
        break;
    }
    $i++;
    $j++;

}
if (!isset($needle[$i])) {
    echo "YES";
}
else{
    echo "NO ";
}



The short-hand version
$result = false!==strpos($a, 'are');



In order to find a 'word', rather than the occurrence of a series of letters that could in fact be a part of another word, the following would be a good solution.
$string = 'How are you?';
$array = explode(" ", $string);

if (in_array('are', $array) ) {
    echo 'Found the word';
}



It can be done in three different ways:
 $a = 'How are you?';
1- stristr()
 if (strlen(stristr($a,"are"))>0) {
    echo "true"; // are Found
 } 
2- strpos()
 if (strpos($a, "are") !== false) {
   echo "true"; // are Found
 }
3- preg_match()
 if( preg_match("are",$a) === 1) {
   echo "true"; // are Found
 }



$a = 'how are you';
if (strpos($a,'are')) {
    echo 'true';
}



You need to use identical/not identical operators because strpos can return 0 as it's index value. If you like ternary operators, consider using the following (seems a little backwards I'll admit):
echo FALSE === strpos($a,'are') ? 'false': 'true';



The strpos function works fine, but if you want to do case-insensitive checking for a word in a paragraph then you can make use of the stripos function of PHP.
For example,
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
    // Word does not exist
}
else {
    // Word exists
}
Find the position of the first occurrence of a case-insensitive substring in a string.
If the word doesn't exist in the string then it will return false else it will return the position of the word.

Tuesday, 18 September 2018

Extract the first paragraph text from a web page with PHP

This post looks at how to extract the first paragraph from an HTML page using PHP's strpos and substr functions to find the location of the first <p> and </p> tags and get the content between them.

Using strpos and substr

Assuming the content to extract the paragraph from is in the variable $html (which may have come from a file, database, template or downloaded from an external website), use the following code to work out the position of the first <p> tag, the first </p> tag after that tag, and then get all the HTML between them including the opening and closing tags:
$start = strpos($html, '<p>');
$end = strpos($html, '</p>', $start);
$paragraph = substr($html, $start, $end-$start+4);
Line 1 gets the position of the first opening <p> tag
Line 2 gets the position of the first </p> after the first opening <p>
Line 3 then uses substr to get the HTML. The third parameter is the number of characters to copy and is calculated by subtracting $start from $end and adding on the length of "</p>" so it is included in the extracted HTML.

Converting to plain text

If the extracted paragraph needs to be in plain text rather than HTML, use the following to remove the HTML tags and convert HTML entities into normal plain text:
$paragraph = html_entity_decode(strip_tags($paragraph));

Related posts:

Wednesday, 3 June 2015

PHP: Server Side Browser Detection

A Set of functions to tell what type of browser a surfer is using 
<?php
function inAgent($agent) {    
 $notAgent = strpos($_SERVER['HTTP_USER_AGENT'],$agent) === false;
 return !$notAgent;
}

function isIE() {
 if (inAgent('MSIE') && !isOpera()) {
  return true;
 }
 return false;
}

function isSafari() {
 $br = new Browser;
 if ($br->Platform == "MacIntosh"||inAgent('Safari')) {
  return true;
 }
 return false;
}

function isFF() {
 if (inAgent('Firefox')) {
  return true;
 }
 return false;
}

function isNS4() {
 if ((!inAgent('MSIE')) && (inAgent('Mozilla/4'))) {
  return true;
 }
 return false;
}

function isIE7() {
 if (inAgent('MSIE 7') && !inAgent('Opera')) {
  return true;
 }
 return false;
}

function isOpera() {
 if (inAgent('Opera')) {
  return true;
 }
 return false;
}
?>

Monday, 29 September 2014

strpos in PHP

 PHP Strpos() function is utilized to returns the  position of the beginning of the first instance of the string if found and false value otherwise.

Syntax:

strpos(string,find,start)
string : Required. Specifies the string to search

find : Required.Specifies the string being searched for.

start : Optional. Specifies the position at which the search should begin.

Note : This function is case-sensitive.

Example:

<?php
echo stripos("Good Morning","or");
?>
Output will be:
6

Friday, 19 September 2014

PHP checking multiple words in a long one word string

<?php
$haystack = 'hihowareyoudoingtoday?';
$needles = array('hi','how','are','you');
$matches = 0;
foreach($needles as $needle) { // create a loop, foreach string
    if(strpos($haystack, $needle) !== false) { // use stripos and compare it in the parent string
        $matches++; // if it matches then increment.
    }
}

echo $matches; // 4
?>

Thursday, 4 September 2014

PHP: Strings in PHP

They are sequences of characters, like "PHP supports string operations".
NOTE: Built-in string functions is given in function reference PHP String Functions
Following are valid examples of string
$string_1 = "This is a string in double quotes";
$string_2 = "This is a somewhat longer, singly quoted string";
$string_39 = "This string has thirty-nine characters";
$string_0 = ""; // a string with zero characters
Singly quoted strings are treated almost literally, whereas doubly quoted strings replace variables with their values as well as specially interpreting certain character sequences.
<?
$variable = "name";
$literally = 'My $variable will not print!\\n';
print($literally);
$literally = "My $variable will print!\\n";
print($literally);
?>
This will produce following result:
My $variable will not print!\n
My name will print
There are no artificial limits on string length - within the bounds of available memory, you ought to be able to make arbitrarily long strings.
Strings that are delimited by double quotes (as in "this") are preprocessed in both the following two ways by PHP:
  • Certain character sequences beginning with backslash (\) are replaced with special characters
  • Variable names (starting with $) are replaced with string representations of their values.
The escape-sequence replacements are:
  • \n is replaced by the newline character
  • \r is replaced by the carriage-return character
  • \t is replaced by the tab character
  • \$ is replaced by the dollar sign itself ($)
  • \" is replaced by a single double-quote (")
  • \\ is replaced by a single backslash (\)

String Concatenation Operator

To concatenate two string variables together, use the dot (.) operator:
<?php
$string1="Hello World";
$string2="1234";
echo $string1 . " " . $string2;
?>
This will produce following result:
Hello World 1234
If we look at the code above you see that we used the concatenation operator two times. This is because we had to insert a third string.
Between the two string variables we added a string with a single character, an empty space, to separate the two variables.

Using the strlen() function

The strlen() function is used to find the length of a string.
Let's find the length of our string "Hello world!":
<?php
echo strlen("Hello world!");
?>
This will produce following result:
12
The length of a string is often used in loops or other functions, when it is important to know when the string ends. (i.e. in a loop, we would want to stop the loop after the last character in the string)

Using the strpos() function

The strpos() function is used to search for a string or character within a string.
If a match is found in the string, this function will return the position of the first match. If no match is found, it will return FALSE.
Let's see if we can find the string "world" in our string:
<?php
echo strpos("Hello world!","world");
?>
This will produce following result:
6
As you see the position of the string "world" in our string is position 6. The reason that it is 6, and not 7, is that the first position in the string is 0, and not 1.

How would you find out if a string contains another string in PHP?

Suppose we have a string that is stored in a PHP variable called $aString. And we want to find out if inside of $aString there is another substring – let’s just say for the sake of an example that we are looking for the string “Waldo” inside of the larger string.
Now let’s say that the name of the larger string ($aString) is this: “Where is Waldo?”. And, we just want to find out if $aString contains “Waldo”. PHP provides us with a function called strpos that will allow us to find the existence of one string inside of another. Here is an example of how to use the strpos function:

Example of how to find out if one string contains another in PHP

if (strpos($aString,'Waldo') !== false) {
    echo 'I found Waldo!';
}
But, there is something you should be aware of when using the strpos function: if you are looking for “Waldo” inside a string that looks like this: “heyWaldo are you there?”, then the strpos function will return successfully with the string positon of “Waldo”, basically saying that “Waldo” was indeed found. This is of course a problem if you only want to search for the string “Waldo” as a separate word, and not as part of another word.

Strpos never returns true

One thing about the strpos function that you should remember is that it never returns the boolean value of true. The strpos function returns a value indicating the position of the first occurrence of the substring being searched for. If the substring is not found “false” is returned instead – which is why in the code above we check for false instead of true.

!== vs != in PHP

One thing worth noting in the code above is that we used the !== operator instead of the != operator (which has one less “=”). What’s the difference between the 2 operators?
You can think of the !== operator as being more ‘strict’ than the != operator. This is because the !== operator will say that the two operands being compared are not equal only if the type of the two operands are the same, but their values are not equal.
This is desirable behavior because the strpos function can return a 0 if the string being searched contains the substring as the very first element. The 0 would represent the 0th index of the larger string – meaning the first position in that string. So, if $aString is “Waldo is here”, and we are searching for “Waldo”, then the strpos function will return a 0. This means that the check being performed will be to see if 0 is not equal to false. But the problem is that 0 is also considered as the integer equivalent of the boolean ‘false’ in PHP, which means that the statement “0 != false” will be considered false, because 0 is equal to false in PHP.
But, if we run “0 !== false” instead, then that statement will be considered to be true, because it just adds the additional check to see if 0 and false are of the same type. Since 0 is an integer and false is a boolean, clearly they are not equal so comparing the 0 and false for inequality returns true unlike the “0 != false” check, which returns false.

if we had this code instead – where we use != and not !== – then it would be a problem:

Problematic code to find a substring inside a larger string

if (strpos($aString,'Waldo') != false) {
    echo 'I found Waldo!';
}
The code above can result in problems for the reasons discussed above. It’s always better to use !== instead of !=.

== AND === operators in PHP

When comparing values in PHP for equality you can use either the == operator or the === operator.

What’s the difference between these 2?

Well, it’s quite simple. 
==  referes to Equality

=== referes to Identity
 
The == operator just checks to see if the left and right values are equal.  

But, the === operator (note the extra “=”) actually checks to see if the left and right values are equal, and also checks to see if they are of the same variable type (like whether they are both booleans, ints, etc.).  


=== means exact value, so for true it has to be true, while == checks for the meaning of the value, so true will be also a value of '1' or a whatever String. 

It’s better to understand when and why you would need to use the === operator versus the == operator. 

When developing in PHP, you may find a time when you will need to use the strpos function.
When using the strpos function, it may return 0 to mean that the string you are searching for is at the 0th index (or the very first position) of the other string that you are searching. 

Suppose, for whatever reason, we want to make sure that an input string does not contain the string “xyz”.

Then we would have this PHP code:
//bad code:
if ( strpos( $inputString, 'xyz' ) == false ) {
  
    // do something
 }

But, there is a problem with the code above: 

Because strpos will return a 0 (as in the 0th index) if the strpos variable happens to have the ‘xyz’ string at the very beginning of $inputString. 

But, the problem is that a 0 is also treated as false in PHP, and when the == operator is used to compare 0 and false, PHP will say that the 0 and false are equal.

That is a problem because it is not what we wanted to have happen – even though the $inputString variable contains the string ‘xyz’, the equality of 0 and false tells us that $inputString does not contain the ‘xyz’ string. 

So, there is a problem with the way the return value of strpos is compared to the boolean value of ‘false’. 

But, what is the solution? 

Well, as you probably guessed, we can simply use the === operator for comparison. And, as we described earlier, the === operator will say that the 2 things being compared are equal only if both the type and value of the operands are also equal. 

So, if we compare a 0 to a false, then they will not be considered equal – which is exactly the kind of behavior we want. Here is what the good code will look like:
//good code:
if ( strpos( $inputString, 'xyz' ) === false ) {
  
    // do something
 }