1

Can someone please put me out of my misery and explain why I'm missing the middle value when I try to push the results of a preg_match into another array? It's either something silly or a vast gap in my understanding. Either way I need help. Here is my code:

<?php 

$text = 'The group, which gathered at the Somerfield depot in Bridgwater, Somerset, 
        on Thursday night, complain that consumers believe foreign meat which has been 
        processed in the UK is British because of inadequate labelling.';

$word = 'the';

preg_match_all("/\b" . $word . "\b/i", $text, $matches, PREG_OFFSET_CAPTURE);

$word_pos = array();


for($i = 0; $i < sizeof($matches[0]); $i++){

    $word_pos[$matches[0][$i][0]] = $matches[0][$i][1];

}



    echo "<pre>";
    print_r($matches);
    echo "</pre>";

    echo "<pre>";
    print_r($word_pos);
    echo "</pre>";

?>

I get this output:

Array
(
[0] => Array
    (
        [0] => Array
            (
                [0] => The
                [1] => 0
            )

        [1] => Array
            (
                [0] => the
                [1] => 29
            )

        [2] => Array
            (
                [0] => the
                [1] => 177
            )

    )

)
Array
(
[The] => 0
[the] => 177
)

So the question is: why am I missing the [the] => 29? Is there a better way? Thanks.

3 Answers 3

1

PHP arrays are 1:1 mappings, i.e. one key points to exactly one value. So you are overwriting the middle value since it also has the key the.

The easiest solution would be using the offset as the key and the matched string as the value. However, depending on what you want to do with the results a completely different structure might be more appropriate.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! Hours of endless and fruitless trawling spared!
1

First you assign $word_pos["the"] = 29 and then you OVERWRITE IT with $word_pos["the"] = 177.

You don't overwrite The because indexes are case sensitive.

So maybe use an array of objects like this:

$object = new stdClass;
$object->word = "the"; // for example
$object->pos = 29; // example :)

and assign it to an array

$positions = array(); // just init once
$positions[] = $object;

alternatively you can assign an associative array instead of the object, so it would be like

$object = array(
    'word' => 'the',
    'pos' => 29
);

OR assign the way you do, but instead of overwriting, just add it to an array, like:

$word_pos[$matches[0][$i][0]][] = $matches[0][$i][1];

instead of

$word_pos[$matches[0][$i][0]] = $matches[0][$i][1];

so you get something like:

Array
(
[The] => Array
      (
         [0] => 0
      )
[the] => Array
      (
         [0] => 29
         [1] => 177
      )
)

Hope that helps :)

Comments

1

What is happening actually :

when i=0,
$word_pos[The] = 0   //mathches[0][0][0]=The 
when i=1
$word_pos[the] = 29       
when i=3
$word_pos[the] = 177  //here this "the" key overrides the previous one
                      //so your middle 'the' is going to lost :(

Now an array based solution can be like this :

for($i = 0; $i < sizeof($matches[0]); $i++){

    if (array_key_exists ( $matches[0][$i][0] , $word_pos ) ) {

        $word_pos[$matches[0][$i][0]] [] = $matches[0][$i][1];

    }

    else $word_pos[$matches[0][$i][0]] = array ( $matches[0][$i][1] );

}

Now if you dump $word_pos the output should be :

Array
(
[The] => Array
    (
    [0] => 0
        )
    [the] => Array 
        (
             [0] => 29 ,
             [1] => 177
        )
    )

Hope that helps.

Reference : array_key_exist

1 Comment

@Matt Welcome , hope that serve your purpose :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.