3v4l.org

run code in 300+ PHP versions simultaneously
<?php // Sample data $data = [ 'Wellington New Zealand', 'Florida United States of America', 'Quebec Canada', 'Something Country XYZ (formally ABC)', ]; // Array of all possible countries $countries = [ 'United States of America', 'Canada', 'New Zealand', 'Country XYZ (formally ABC)', ]; // The begining and ending pattern delimiter for the RegEx $delim = '/'; /*************************************************** * Option 1 * * Simple but potentially flawed depending on data * **************************************************/ matchAndShowData($data, $countries, $delim, implode('|', $countries)); echo PHP_EOL, PHP_EOL; /******************************* * Option 2 * * Always escape, just in case * ******************************/ // This is an alternative form of the above, and is arguably overkill for this specific // situation, but I always run my code preg_quote, just in case. // This function will ensure that just in case a country has a RegEx modifier that it gets // properly escaped. $patternParts = array_map(fn(string $country) => preg_quote($country, $delim), $countries); // Implode the cleaned countries using the RegEx pipe operator which means "OR" matchAndShowData($data, $countries, $delim, implode('|', $patternParts)); function matchAndShowData(array $data, array $countries, string $delim, string $countryParts): void { $pattern = "^(?<region>.*?) (?<country>$countryParts)$"; foreach($data as $d) { if(preg_match($delim . $pattern . $delim, $d, $matches)){ echo sprintf('%1$s, %2$s', $matches['region'], $matches['country']), PHP_EOL; } else { echo 'NO MATCH: ' . $d, PHP_EOL; } } }
Output for 7.4.0 - 7.4.33, 8.0.1 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.19, 8.3.0 - 8.3.7
Wellington, New Zealand Florida, United States of America Quebec, Canada NO MATCH: Something Country XYZ (formally ABC) Wellington, New Zealand Florida, United States of America Quebec, Canada Something, Country XYZ (formally ABC)

preferences:
142.84 ms | 403 KiB | 123 Q