Search code examples
phpstringsearchstrpos

Best way to find matches of several substrings in string?


I have $a=array('1str','2str','3str') and $str ='123 2str 3str 1str'
and trying to do a simple thing - find the position of each item of $a in $str.

It's easy to be done with loops and strpos, but I'm curious what is the best (and short, actually) way to get the positions?

Actually I need to get the nearest of the found items in string (2str)


Solution

  • If you need all offsets, could also use preg_match_all function and flag PREG_OFFSET_CAPTURE

    if(preg_match_all('/'.implode('|', $a).'/', $str, $out, PREG_OFFSET_CAPTURE))
      print_r($out[0]);
    

    Useful if you need to match such as \b word boundaries or do caseless matching using the i flag.

    As @mike.k commented: If $a contains characters with special meaning inside a regex pattern, need to escape those first: array_map(function ($v) { return preg_quote($v, "/"); }, $a)


    To get the one that's closest to start, don't need all offsets. Could do that with preg_match and the simple pattern 1str|2str|3str (see test at eval.in).

    if(preg_match('/'.implode('|', $a).'/', $str, $out, PREG_OFFSET_CAPTURE))
      echo "The substring that's closest to start is \"".$out[0][0]."\" at offset ".$out[0][1];
    

    The substring that's closest to start is "2str" at offset 4


    If you don't need offset/regex at all, another idea for the first match: Sorting with usort by pos

    usort($a, function ($x, $y) use (&$str) {
      return (strpos($str, $x) < strpos($str, $y)) ? -1 : 1;
    });
    

    echo $a[0]; > 2str  (anonymous functions with usort require at least PHP 5.3)