explode - PHP Finding Match in String, Changing it Then Using Updated String

I've searched til I am blue in the face and have yet to find a solution to this. I want to check a string to see if one of the 2 letter state abbreviations are in it. I can find it and uppercase it, but it also uppercase the abbreviation if it is part of a word (which I do not want it to do).

My code below outputs "WAnt To Work In Eastern WA?"

when I want it to output "Want To Work In Eastern WA?".

Here is what I am working with, hopefully someone can tell me what I am doing wrong. Thank you!

$newheading = "Want To Work In Eastern Wa?";  // This variable is not always the same.  
$states = "Al Ak Az Ar Ca Co Ct De Fl Ga Hi Id Il In Ia Ks Ky La Me Md Ma Mi Mn Ms Mo Mt Ne Nv Nh Nj Nm Ny Nc Nd Oh Ok Or Pa Ri Sc Sd Tn Tx Ut Vt Va Wa Wv Wi Wy";
    $pieces = explode(" ", trim($newheading));
    
    foreach($pieces as $v) {
            if ((strlen($v) == 2) && ($v != "In") && ($v != "Or")) {
                $newv = strtoupper($v);
                $out =  str_replace($v, $newv, $pieces);
                $out = implode(" ", $pieces);
                $newheading = $out;
                break;
            }
    }

Answer

Solution:

You can use a regex joining the states on OR and look for word-boundaries |\b or a space \s:

$states = explode(' ', $states);  // or just define as an array
$states = implode('', $states);

$newheading = preg_replace_callback("/|\b($states)|\b/", function($m) {
                                                           return strtoupper($m[0]);
                                                       }, $newheading);

I'm not sure what you're doing with "In" and "Or", but just remove them from $states.

If the string could contain wa or wA for example, then you want to add the i modifier to the end for case insensitive.

Source