Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 12-31-2012, 09:16 PM   PM User | #1
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
strpos with multiple words

Hi I am trying to check for either of 2 words, in a string
and then do something.

Right know this below only works with just one word?
is there a simple to check for multiple words?

PHP Code:

$string 
"one two three four five";

$find "two";
//$find2 = "three";

$status strpos($string$find);

if (
$status == true) echo "Found";
else echo 
"Not Found"
Thanks
Sonny

Last edited by sonny; 12-31-2012 at 09:33 PM..
sonny is offline   Reply With Quote
Old 12-31-2012, 09:23 PM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,648
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
regex.
Also, using if ($status == true) is incorrect. You should be using if ($status !== false) instead, consider searching for one:
PHP Code:
$string "one two three four five";

$find "one";
//$find2 = "three";

$status strpos($string$find);

if (
$status == true) echo "Found";
else 
"Not Found"
Would produce no results (I presume you intend to actually print the not found, but in this one its just a string sitting by its lonesome ).
Fou-Lu is offline   Reply With Quote
Old 12-31-2012, 09:28 PM   PM User | #3
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
Quote:
Originally Posted by Fou-Lu View Post
regex.
Also, using if ($status == true) is incorrect. You should be using if ($status !== false) instead, consider searching for one:
PHP Code:
$string "one two three four five";

$find "one";
//$find2 = "three";

$status strpos($string$find);

if (
$status == true) echo "Found";
else 
"Not Found"
Would produce no results (I presume you intend to actually print the not found, but in this one its just a string sitting by its lonesome ).
of course just forgot the echo thats all, as for that if ($status == true) echo "Found";
thats been working correctly for years, my question was how do I check for another
word as well


Have a nice New Year tonight
Sonny
sonny is offline   Reply With Quote
Old 12-31-2012, 09:49 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,648
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
Use regex with a preg_match_all instead.

$status == true is incorrect. If you find position at 0, that is a valid offset but will fail to pass a true check. You need to check for !== false (such as my example with "one" where it finds no results in the above string).
Fou-Lu is offline   Reply With Quote
Old 12-31-2012, 11:06 PM   PM User | #5
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
In case anyone needs to do something like this
got it, was even simpleier then I first thought.

PHP Code:
 $find = array('seven''five''ten');
 
$string "one two three four five";
 
         foreach (
$find as $n) {
    if (
strpos($string$n) !== false)
    echo 
"Found";} 
Sonny
sonny is offline   Reply With Quote
Old 12-31-2012, 11:16 PM   PM User | #6
tangoforce
Senior Coder

 
tangoforce's Avatar
 
Join Date: Feb 2011
Location: Your Monitor
Posts: 3,504
Thanks: 45
Thanked 439 Times in 428 Posts
tangoforce will become famous soon enoughtangoforce will become famous soon enough
Quote:
Originally Posted by sonny View Post
In case anyone needs to do something like this
got it, was even simpleier then I first thought.

PHP Code:
 $find = array('seven''five''ten');
 
$string "one two three four five";
 
         foreach (
$find as $n) {
    if (
strpos($string$n) !== false)
    echo 
"Found";} 
Sonny
Explode $string into an array and then use http://www.php.net/in_array on it.
__________________
Please wrap your code in [php] tags. It is a sticky topic and it HELPS us to HELP YOU!
TIP: Coding styles and $end errors :::::::::: TIP: Warning: Cannot modify header information - headers already sent :::::::::: TIP: Quotes / Parse error: syntax error, unexpected T_..
PHP Code:
//Please don't use this for your form processing:
if (isset($_POST['submit']))
//Internet explorer has a bug and does not always send the submit value. 
Explanation: The IE if(isset($_POST['submit'])) bug explained.
tangoforce is offline   Reply With Quote
Old 12-31-2012, 11:18 PM   PM User | #7
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,648
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
With an array you could easily implode them as well for the pattern:
PHP Code:
$find = array('seven''five''ten');
$string "one two three four five";
array_map($find'preg_quote');
$sPattern '/\b(?:' implode('|'$find) . ')\b/';
preg_match_all($sPattern$string$matchesPREG_OFFSET_CAPTURE); 
Then iterate the $matches. They'll be in offset 0, and are an array containing the offsets and the string (if you need the offsets for whatever reason). If you don't need the offsets, drop the modifier and simply iterate the $matches[0].

This would be better since you don't need to worry about adding spaces and matching what you don't want to match. If you were looking for "fifty", it would also match "fiftyfive" while the pattern would not. This way you also don't need to concern yourself with order.
The pattern matching does take a lot longer though, but the returns of the strpos will degrade as the find counts increase.

Edit:
I like Tango's suggestion as well. That will eliminate the issue with finding things like "fifty" and matching "fiftyfive" for example.
Edit:
Assuming of course you don't actually care about the offset, in which case I'd still suggest using preg.


Last edited by Fou-Lu; 12-31-2012 at 11:22 PM..
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
tangoforce (01-01-2013)
Old 01-01-2013, 12:54 AM   PM User | #8
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
Hi Guys

Am I missing something? does this not work?
it seems to be working for me, or am I getting
odd results?. put this in a file and test yourself.

PHP Code:
 $find = array('seven''five''ten');
 
$string "one two three four five";
 
         foreach (
$find as $n) {
    if (
strpos($string$n) !== false)
    echo 
"Found";} 
Sonny
sonny is offline   Reply With Quote
Old 01-01-2013, 01:05 AM   PM User | #9
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
Quote:
Originally Posted by tangoforce View Post
Explode $string into an array and then use http://www.php.net/in_array on it.
Yes I like this way, very simple and clean
going to test that

Thanks
Sonny
sonny is offline   Reply With Quote
Old 01-01-2013, 01:33 AM   PM User | #10
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
Hi this is something like what I need to do, ln_array is most likely not
the best way to go, but I may be wrong.

Is this the best way to do that?, I am looking for a page that "either"
has test or admin in its name, that's basically what I need to do.

PHP Code:
$find = array('test''admin');
$string $_SERVER['REQUEST_URI'];

         foreach (
$find as $n) {
                 if (
strpos($string$n) !== false)
    echo 
"Found";} 
Sonny
sonny is offline   Reply With Quote
Old 01-01-2013, 02:19 AM   PM User | #11
tangoforce
Senior Coder

 
tangoforce's Avatar
 
Join Date: Feb 2011
Location: Your Monitor
Posts: 3,504
Thanks: 45
Thanked 439 Times in 428 Posts
tangoforce will become famous soon enoughtangoforce will become famous soon enough
Whoa, looks like the goal posts have just moved!
__________________
Please wrap your code in [php] tags. It is a sticky topic and it HELPS us to HELP YOU!
TIP: Coding styles and $end errors :::::::::: TIP: Warning: Cannot modify header information - headers already sent :::::::::: TIP: Quotes / Parse error: syntax error, unexpected T_..
PHP Code:
//Please don't use this for your form processing:
if (isset($_POST['submit']))
//Internet explorer has a bug and does not always send the submit value. 
Explanation: The IE if(isset($_POST['submit'])) bug explained.
tangoforce is offline   Reply With Quote
Old 01-01-2013, 03:34 PM   PM User | #12
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,648
Thanks: 4
Thanked 2,450 Times in 2,419 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
I think its just the understanding that has changed

These approaches have different purposes.
Using in_array or an intersection of arrays looks for the same items, not containment items. It is also the fastest of the three since you are comparing individual tokens to other individual tokens.
Using strpos will find partials. It takes longer than an array check since you need to compare the entire string each time. It cannot find multiples.
Using preg has the greatest flexibility in what you can do. You can choose to either make partials or exact matches. It is the slowest of the three, but can also find duplicates (the in_array can as well).

If your goal is to check if a string contains any of the items and can match partials, without caring of which it matches, simply write a function that returns a boolean:
PHP Code:
function stringContainsAnyOf($s, array $a)
{
    
$result false;
    
reset($a);
    while (!
$result && ($cur current($a)))
    {
        
$result strpos($s$cur) !== false;
        
next($a);
    }
    return 
$result;

That would return true so long as any one of the array items match, but you cannot tell which one it was nor whether it was a partial. Likewise, if you want to use identical, you would use in_array.
The preg wouldn't require a function to do this since it returns all the matches as an array. No matches = no items in array.

Last edited by Fou-Lu; 01-01-2013 at 03:37 PM..
Fou-Lu is offline   Reply With Quote
Old 01-02-2013, 05:31 AM   PM User | #13
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
Quote:
Originally Posted by tangoforce View Post
Whoa, looks like the goal posts have just moved!
Please take another look at the first post, nothing has changed
It's still a string, that needs to be checked for two words "efficiently".
and with minimal code as always.

I had this working since the 4th post like shown below
can you give feedback as to why this is not a good way?
It's been working perfect so far.

PHP Code:
 $find = array('seven''five''ten');
 
$string "one two three four five";
 
         foreach (
$find as $n) {
    if (
strpos($string$n) !== false)
    echo 
"Found";} 
Hope you had a nice New Year!.
Sonny
sonny is offline   Reply With Quote
Old 01-02-2013, 04:10 PM   PM User | #14
tangoforce
Senior Coder

 
tangoforce's Avatar
 
Join Date: Feb 2011
Location: Your Monitor
Posts: 3,504
Thanks: 45
Thanked 439 Times in 428 Posts
tangoforce will become famous soon enoughtangoforce will become famous soon enough
Quote:
Originally Posted by sonny View Post
I had this working since the 4th post like shown below
can you give feedback as to why this is not a good way?
It's not that it isn't a good way, there is nothing wrong with what you're doing. All I'm saying is that I would have use in_array() - a php function (that will no doubt be slightly quicker and more efficient) to check if each word is in the array.

As I said, nothing wrong with what you've done but there are always several ways of doing the same thing
__________________
Please wrap your code in [php] tags. It is a sticky topic and it HELPS us to HELP YOU!
TIP: Coding styles and $end errors :::::::::: TIP: Warning: Cannot modify header information - headers already sent :::::::::: TIP: Quotes / Parse error: syntax error, unexpected T_..
PHP Code:
//Please don't use this for your form processing:
if (isset($_POST['submit']))
//Internet explorer has a bug and does not always send the submit value. 
Explanation: The IE if(isset($_POST['submit'])) bug explained.
tangoforce is offline   Reply With Quote
Old 01-02-2013, 04:35 PM   PM User | #15
sonny
Regular Coder

 
sonny's Avatar
 
Join Date: Apr 2008
Location: United States
Posts: 567
Thanks: 88
Thanked 0 Times in 0 Posts
sonny can only hope to improve
Quote:
Originally Posted by tangoforce View Post
It's not that it isn't a good way, there is nothing wrong with what you're doing. All I'm saying is that I would have use in_array() :
problem was, in_array only works with exact match, or I would have used it.

Thanks
Sonny
sonny is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:16 PM.


Advertisement
Log in to turn off these ads.