16

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.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Chad Cardiff
  • 459
  • 3
  • 8
  • 23

7 Answers7

21

try preg match for multiple

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

strpos() with multiple needles?

Community
  • 1
  • 1
user3270784
  • 460
  • 5
  • 5
  • 1
    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](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). - [From Review](/review/low-quality-posts/10897929) – Luca Detomi Jan 15 '16 at 08:09
  • @LucaDetomi are you sure? – CoderPi Jan 15 '16 at 08:25
  • 1
    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. – Luca Detomi Jan 15 '16 at 08:26
  • It's actually the wrong answer probably because copy/paste. The /i is the equivalent for stripos() for strpos the i needs to be removed – John Oct 19 '18 at 00:17
18

I just used the OR statement (||)

<?php 
  if ((strpos($color,'1') || strpos($color,'2') || strpos($color,'3')) === true) 
   {
      //do nothing
   } else { 
      echo "checked"; 
   } 
?>
gagarine
  • 4,190
  • 2
  • 30
  • 39
Chad Cardiff
  • 459
  • 3
  • 8
  • 23
  • If `$color='25 48';` what will be the out put? `strpos($color,'5')` will found digit 5 but you have value 25 and 48. – MD SHAHIDUL ISLAM Oct 06 '13 at 05:56
  • 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 . – Salem Nov 19 '15 at 14:31
  • 5
    `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. – Matt K Dec 08 '15 at 18:20
  • 1
    but checking against `!== false` will do it. – Cornel Raiu Jan 06 '16 at 09:38
  • 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 ( ) – hanshenrik Dec 26 '17 at 18:54
  • 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 upvotes – mickmackusa Sep 27 '19 at 21:28
  • **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 */ }` – c00000fd May 18 '20 at 00:43
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>";         
    }       
  }
Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
  • 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. – JeremyCanfield Dec 09 '17 at 17:48
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";
}
?>
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
  • 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! +rep – Chad Cardiff Oct 06 '13 at 06:06
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';
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
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;
  }
}
Nenad Jeremic
  • 74
  • 1
  • 5
0
if (preg_match('/string1|string2|string3/i', $str)){
  //if one of them found
}else{
 //all of them can not found
}
hakki
  • 6,181
  • 6
  • 62
  • 106