<?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;
}
}
}
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)