Reputation: 137
How do I match a pattern string with group of variables defined by {{VARIABLE}}
from a string that contains the {{VARIABLE}}
to an array?
Example:
I have the Pattern String:
$pattern = "Image_{{DATE}}.{{EXTENSION}}";
And I would like to pass the match string
$string = "Image_2016-05-26.png";
And after passing both strings to the function, return
$result = [
"DATE": "2016-05-26",
"EXTENSION": "png"
];
This includes, but not limited to the example variable:
$pattern = "Image_{{YEAR}}-{{MONTH}}-{{DAY}}.{{EXTENSION}}";
$string = "Image_2016-05-26.png";
// ------------------------------
$result = [
"YEAR" => "2016",
"MONTH" => "05",
"DAY" => "26",
"EXTENSION" => ".png"
];
(Optional, I think this is the hardest) But also only return values if they're found:
$pattern = "Image_{{DATE}}.{{EXTENSION}}";
$string = "Image_2016-05-26";
// ------------------------------
$result = [
"DATE" => "2016-05-26",
];
Is there any way to build a function passing pattern
and string
as variables and achieve result
?
Thanks!
Upvotes: 1
Views: 45
Reputation: 43743
Here's the overview of the steps you would need to do:
First, escape all of the characters which have special meaning to regex, except for the {{
and the }}
. Next, replace all instances of {{
with (?P<
. Next, replace all instances of }}
with >.*?)
. Then add the prefix of /^
and the suffix of $/
to the string.
That would convert the following pattern:
Image_{{DATE}}.{{EXTENSION}}
Into the following regex pattern:
/^Image_(?P<DATE>.*?)\.(?P<EXTENSION>.*?)$/
Now, use that regex pattern to search for a match. Then loop through all the captured groups in the match and output the name/value pair for each one.
For instance, something like this will work for those examples:
function func_name($pattern, $string) {
$pattern = "/^" . str_replace([".", "{{", "}}"], ["\.", "(?P<", ">.*?)"], $pattern) . "$/";
preg_match($pattern, $string, $result);
return array_filter($result, "is_string", ARRAY_FILTER_USE_KEY);
}
Of course, all of this would be much easier if your input pattern was a proper regex pattern to begin with...
As far as making the extension variable optional, you can make a capturing group optional by adding a ?
after it, but there is no automated way of doing it according to your example because in your example, the .
before the extension is also optional, but there is no indication in the input pattern that that is the case. In other words, you would need to convert it to /^Image_(?P<DATE>.*?)(?:\.(?P<EXTENSION>.*?))?$/
, but there's no way of knowing, based only on that input pattern, that you would need to add the (?: ... )?
optional group around the extension and the preceding period.
Upvotes: 1
Reputation: 313
use php strrt
function
function func_name ($pattern, $params) {
$toReplace = [];
$res = array_walk($params, function($v, $k) use (&$toReplace) {
$toReplace['{{' . $k . '}}'] = $v;
});
return strtr($pattern, $toReplace);
}
$params = [
"YEAR" => "2016",
"MONTH" => "05",
"DAY" => "26",
"EXTENSION" => "png"
];
$pattern = "Image_{{YEAR}}-{{MONTH}}-{{DAY}}.{{EXTENSION}}";
echo func_name($pattern, $params); // Image_2016-05-26.png
Upvotes: 0