Checking for multiple strpos values
Asked Answered
J

7

17

I am wondering how to complete multiple strpos checks.

Let me clarify:
I want strpos to check the variable "COLOR" to see if any numbers from 1 to 8 are anywhere in the variable. If any numbers from 1 to 8 are present, I want to echo "selected".

Examples:
Let's say only the number 1 is in the variable, it will echo "selected".
Let's say the numbers 1 2 and 3 are in the variable, it will echo "selected."
Let's say the numbers 3 9 25 are in the variable, it will echo "selected" (because of that 3!!).
Let's say only the number 9 is in the variable, it will NOT echo.
Let's say the numbers 9 25 48 are in the variable, it will NOT echo.

Jankell answered 6/10, 2013 at 5:25 Comment(3)
are you getting numbers in array?Nopar
Is there any space in this string value of variable in which you want to find. as 1 2 25 48Attributive
There are spaces between the numbers, but I figured out how to do it, the code below works! Thank you.Jankell
J
19

I just used the OR statement (||)

<?php 
  if ((strpos($color,'1') || strpos($color,'2') || strpos($color,'3')) === true) 
   {
      //do nothing
   } else { 
      echo "checked"; 
   } 
?>
Jankell answered 6/10, 2013 at 5:33 Comment(7)
If $color='25 48'; what will be the out put? strpos($color,'5') will found digit 5 but you have value 25 and 48.Attributive
This is the only code works better for small values . if you have bigger values us a function that compare each value to the pattern you have .Psoas
strpos() returns the position of where the needle exists in the string, so if any of those numbers are in the first position it would return 0 and your code would fail because you're doing a boolean check. Also, strpos() would never return a boolean TRUE so checking === true is incorrect.Leavelle
but checking against !== false will do it.Goldengoldenberg
your code is still bugged. only 8 will not bug out. change it to if ((strpos($color,'1') || strpos($color,'2') || strpos($color,'3') || strpos($color,'4') || strpos($color,'5') || strpos($color,'6') || strpos($color,'7') || strpos($color,'8')) === true) and it should work correctly. ps, i just added an extra pair of ( )Piaffe
Checking for === true is useless here, just omit it. This answer is using unstable techniques that also do not scale well. This answer will misinform more people than it informs because of the green tick and upvotesElectronic
This is very wrong. Don't use it! No wonder there's so much buggy PHP code. And how is it an upvoted answer? Anyway, strpos may return 0 for the 1st char position in the string that it finds the match in. The check must be if(strpos($color,'1') !== false || strpos($color,'2') !== false){ /* found 1 or 2 */ }Mistassini
S
22

try preg match for multiple

if (preg_match('/word|word2/i', $str))

strpos() with multiple needles?

Scalp answered 14/1, 2016 at 19:37 Comment(4)
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. - From ReviewWilheminawilhide
@LucaDetomi are you sure?Respective
This is an automatic comment because your answer was flagged as too short. I suggest you to add more details to let users understand "why" your solution is correct andmaybe why this could be the best one.Wilheminawilhide
It's actually the wrong answer probably because copy/paste. The /i is the equivalent for stripos() for strpos the i needs to be removedFasto
J
19

I just used the OR statement (||)

<?php 
  if ((strpos($color,'1') || strpos($color,'2') || strpos($color,'3')) === true) 
   {
      //do nothing
   } else { 
      echo "checked"; 
   } 
?>
Jankell answered 6/10, 2013 at 5:33 Comment(7)
If $color='25 48'; what will be the out put? strpos($color,'5') will found digit 5 but you have value 25 and 48.Attributive
This is the only code works better for small values . if you have bigger values us a function that compare each value to the pattern you have .Psoas
strpos() returns the position of where the needle exists in the string, so if any of those numbers are in the first position it would return 0 and your code would fail because you're doing a boolean check. Also, strpos() would never return a boolean TRUE so checking === true is incorrect.Leavelle
but checking against !== false will do it.Goldengoldenberg
your code is still bugged. only 8 will not bug out. change it to if ((strpos($color,'1') || strpos($color,'2') || strpos($color,'3') || strpos($color,'4') || strpos($color,'5') || strpos($color,'6') || strpos($color,'7') || strpos($color,'8')) === true) and it should work correctly. ps, i just added an extra pair of ( )Piaffe
Checking for === true is useless here, just omit it. This answer is using unstable techniques that also do not scale well. This answer will misinform more people than it informs because of the green tick and upvotesElectronic
This is very wrong. Don't use it! No wonder there's so much buggy PHP code. And how is it an upvoted answer? Anyway, strpos may return 0 for the 1st char position in the string that it finds the match in. The check must be if(strpos($color,'1') !== false || strpos($color,'2') !== false){ /* found 1 or 2 */ }Mistassini
E
10

I found the above answers incomplete and came up with my own function:

/**
 * Multi string position detection. Returns the first position of $check found in 
 * $str or an associative array of all found positions if $getResults is enabled. 
 * 
 * Always returns boolean false if no matches are found.
 *
 * @param   string         $str         The string to search
 * @param   string|array   $check       String literal / array of strings to check 
 * @param   boolean        $getResults  Return associative array of positions?
 * @return  boolean|int|array           False if no matches, int|array otherwise
 */
function multi_strpos($string, $check, $getResults = false)
{
  $result = array();
  $check = (array) $check;

  foreach ($check as $s)
  {
    $pos = strpos($string, $s);

    if ($pos !== false)
    {
      if ($getResults)
      {
        $result[$s] = $pos;
      }
      else
      {
        return $pos;          
      }
    }
  }

  return empty($result) ? false : $result;
}

Usage:

$string  = "A dog walks down the street with a mouse";
$check   = 'dog';
$checks  = ['dog', 'cat', 'mouse'];

#
# Quick first position found with single/multiple check
#

  if (false !== $pos = multi_strpos($string, $check))
  {
    echo "$check was found at position $pos<br>";
  }

  if (false !== $pos = multi_strpos($string, $checks))
  {
    echo "A match was found at position $pos<br>";
  }

#
# Multiple position found check
#

  if (is_array($found = multi_strpos($string, $checks, true)))
  {
    foreach ($found as $s => $pos)
    {
      echo "$s was found at position $pos<br>";         
    }       
  }
Egoism answered 18/12, 2015 at 23:16 Comment(1)
Your function and usage work wonderfully. When I implemented this in my app, I changed strpos to stripos so that the function was not case sensitive.Glucose
A
2

If all value is seperated by a space in value then you can do the following. Otherwise ignore it.

It is needed because if you have $color="25"; then strpos will found both 2, 5 and 25 so required result will not come

<?php
$color='1 25 48 9 3';
$color_array = explode(" ",$color);

$find = range(1,8);//array containing 1 to 8

$isFound = false;
foreach($find as $value) {
    if(in_array($value, $color_array)) 
    {
        $isFound = true;
        break;
    }
}

if($isFound) {
    echo "Selected";
}
?>
Attributive answered 6/10, 2013 at 5:59 Comment(1)
Salim, good catch. Though, I do not need to implement this because I won't be entering any other numbers (other than 1 to 8). Instead I will be entering text (such as the color BROWN or DARK GREY). But thank you! +repJankell
E
1

A simple preg_match() call using wordboundaries around a numeric character class will be completely accurate and suitable for your task.

The word boundary metacharacters ensure that full-integer matching is executed -- no false positive (partial) matching occurs.

Code: (Demo)

$array = array(
    'text 1 2 and 3 text',
    'text 3 9 25 text',
    'text 9 25 48 text',
);

foreach ($array as $color) {
    echo "\n---\n$color";
    echo "\n\t" , preg_match('~\b[1-8]\b~', $color, $out) ? "checked (satisfied by {$out[0]})" : 'not found';
    echo "\n\tChad says: " , (strpos($color,'1') || strpos($color,'2') || strpos($color,'3') || strpos($color,'4') || strpos($color,'5') || strpos($color,'6') || strpos($color,'7') || strpos($color,'8') ? 'found' : 'not found');
}

Output:

---
text 1 2 and 3 text
    checked (satisfied by 1)
    Chad says: found
---
text 3 9 25 text
    checked (satisfied by 3)
    Chad says: found
---
text 9 25 48 text
    not found
    Chad says: found

As for how to implement this technique in your script...

if (!preg_match('~\b[1-8]\b~', $color)) {
    echo 'checked';
}
Electronic answered 27/9, 2019 at 21:51 Comment(0)
W
1

I had similar needs so here is function that get position of closest substring in given string, where search substrings are provided in array. It also pass by reference matched substring. Note that order matters in case some substring contains other substring - example: '...' and '.'.

function strpos_arr($haystack, $needleN, $offset = 0, &$needle = '') {
  if (!is_array($needleN)) {
    return strpos($haystack, $needleN, $offset);
  } else {
    $res = FALSE;
    foreach ($needleN as $ind => $item) {
      $pos = strpos($haystack, $item, $offset);
      if ($pos !== FALSE && ($res === FALSE || $pos < $res)) {
        $res = $pos;
        $needle = $item;
      }
    }
    return $res;
  }
}
Wilmer answered 12/4, 2020 at 11:51 Comment(1)
Also note that this function works as strpos in case that second argument is not array.Wilmer
P
0
if (preg_match('/string1|string2|string3/i', $str)){
  //if one of them found
}else{
 //all of them can not found
}
Panto answered 16/2, 2018 at 9:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.