I am having a hard time finishing a regex to catch a correct pattern in my files.
This is my PHP Code that I let run:
$imagesToAdd = [];
foreach (glob($imagePath.'/'.$groupCode.'*.{jpg,png}', GLOB_BRACE) as $filepath) {
$match = (int) preg_match('#'.$imagePath.'/'.$groupCode.' ([^\D]|[-_\d]?) .(png|jpg)#', $filepath);
print $filepath . PHP_EOL;
print $imagePath.'/'.$groupCode.' (|[\D]|[-_\d]) .(png|jpg)' . PHP_EOL;
var_dump($match);
if ($match !== 0) {
$imagesToAdd[] = $filepath;
}
}
The Regex here is '#'.$imagePath.'/'.$groupCode.' ([^\D]|[-_\d]?) .(png|jpg)#'.
Lets use some examples to make clear what my objective is and why its still failing.
Lets say the Regex resolves to this:
\/home\/shop\/test\/release\/20211005131411\/pub\/media\/productImages\/29192-7 ([^\D]|[-_\d]?) .(png|jpg)
it will correctly fetch the provided path as expected. But now comes my problem.
My $groupCode can be either 1, 1-1 or 1123123123-1 or simply only 1123123123. In any case, 1 should not match a provided path that ends onto 123123123-1.png or 12111111.jpg.
So, if the $groupCode is 1, it should only match 1.jpg or 1.png or 1-1.png or 1-9999.jpg.
If the $groupCode is 123-1 it should only match 123-1.jpg or 123-1.png or 123-1-anyothernumber.(png|jpg). What do I have to do in order to get the Regex straight here?
My current approach does not work completely and I am running out of ideas.
CodePudding user response:
First replace the glob() with some static data to get a reproducible example. It is really difficult for us to debug something if we do not have all parts.
$data = [
'/base-path/42.png',
'/base-path/42-1.png',
'/base-path/42.PNG',
'/base-path/21.png'
];
$imagePath = '/base-path';
$groupCode = '42';
Some things to look out for:
- If you put a variable value into a regular expression, you will need to escape the special characters that might be in it - use
preg_quote(). - Validating patterns need to be anchored, otherwise here can be content before and after - use
^and$.
If I understand correctly you're trying to match:
{path}/{code}.{image-extension} and
{path}/{code}-{digits}.{image-extension}
- Digit:
\d - Digits (at least one):
\d - Prefixed with -:
-\d - Optional:
(-\d )? - With image file extension:
(-\d )?\.(jpg|png) - Case insensitive extensions:
(-\d )?\.((?i)jpg|png)
Put together:
$pattern = '(^'.preg_quote($imagePath.'/'.$groupCode).'(-\d )?\\.((?i)png|jpg)$)';
var_dump($pattern);
$imagesToAdd = [];
foreach ($data as $file) {
echo 'Validating: ', $file, PHP_EOL;
$found = preg_match($pattern, $file);
echo $found ? ' - HIT' : ' - MISS', PHP_EOL;
if ($found) {
$imagesToAdd[] = $file;
}
}
var_dump($imagesToAdd);
Output:
string(40) "(^/base\-path/42(-\d )?\.((?i)png|jpg)$)"
Validating: /base-path/42.png
- HIT
Validating: /base-path/42-1.png
- HIT
Validating: /base-path/42.PNG
- HIT
Validating: /base-path/21.png
- MISS
array(3) {
[0]=>
string(17) "/base-path/42.png"
[1]=>
string(19) "/base-path/42-1.png"
[2]=>
string(17) "/base-path/42.PNG"
}
