phpstrposword-boundary

How to implement word boundaries with strpos() to ensure whole word/number is matched?


I am using strpos() function to find the string in an array key members.

foreach($_POST as $k => $v){
    // for all types of questions of chapter 1 only
    $count = 0;
    if(strpos($k, 'chap1') !== false){
        $count++;
    }
}

I know that it works only until the keys are (chap1e1, chap1m1, chap1h1) but when it comes to (chap10e1, chap10m1, chap10h1), my logic won't be working on those.

Isn't there any way, so that, I can distinguish the comparison between (chap1 & chap10)?

Or, Is there any alternative way of doing this?


Solution

  • Basically, preg_match would do just that:

    $count = 0;
    foreach($_POST as $k => $v)
    {
        if (preg_match('/\bchap1[^\d]{0,1}/', $k)) ++$count;
    }
    

    How the pattern works:

    To deal with all of these "chapters" at once, try this:

    $count = array();
    foreach($_POST as $k => $v)
    {
        if (preg_match('/\bchap(\d+)(.*)/', $k, $match))
        {
            $match[2] = $match[2] ? $match[2] : 'empty';//default value
            if (!isset($count[$match[1]])) $count[$match[1]] = array();
            $count[$match[1]][] = $match[2];
        }
    }
    

    Now this pattern is a bit more complex, but not much

    Now, I've turned the $count variable into an array, that will look like this:

    array('1' => array('e1', 'a3'),
          '10'=> array('s3')
    );
    

    When $_POST looks something like this:

    array(
        chap1e1 => ?,
        chap1a3 => ?,
        chap10s3=> ?
    )
    

    What you do with the values is up to you. One thing you could do is to group the key-value pairs per "chapter"

    $count = array();
    foreach($_POST as $k => $v)
    {
        if (preg_match('/\bchap(\d+)/', $k, $match))
        {
            if (!isset($count[$match[1]])) $count[$match[1]] = array();
            $count[$match[1]][$k] = $v;//$match[1] == chap -> array with full post key->value pairs
        }
    }
    

    Note that, if this is a viable solution for you, it's not a bad idea to simplify the expression (because regex's are best kept simple), and just omit the (.*) at the end.
    With the code above, to get the count of any "chap\d" param, simply use:

    echo 'count 1: ', isset($count[1]) ? count($count[1]) : 0, PHP_EOL;