I have a file name where information has to be replaced. Here is a subject sample :
FileA-2014-11-01_K_1_A2_383.xxx
As many files are to be processed, this filename is first matched by a regex, say :
/[a-zA-Z]*-\d{4}-\d{2}-\d{2}_(\w)_(\d)_A2_(\d*)\.xxx$/
This regex will give me, using preg_match, the values to be replaced, here :
- K=>A
- 1=>2
- 383=>666
My first try was to naively use "str_replace", but it fails when patterns are repeated in the string : here i will get :
FileA-2024-22-02_A_2_A2_666.xxx
So the date is also modified by the str_replace (as it was told to do..)
So, i wonder if there is a way to know where is a given match in the string to have a clean replacement. I'm now trying to revert the regex to be able to capture non-replacement blocks, and then insert replaced data. That regex would be :
/([a-zA-Z]*-\d{4}-\d{2}-\d{2}_)\w(_)\d(_A2_)\d*(\.xxx)$/
With that one, i'm able to keep non-replaced parts. I now have to find a kind of index to know the replacement position in the string. I guess I can achieve this way, but is seems somewhat complicated and error prone. Given I only have the initial regex and the map for to=>from replacement, is there a way to do that in a better way?
[EDIT : solution]
<?php
$filename = "FileA-2014-11-01_K_1_A2_383.xxx";
$expected = "FileA-2014-11-01_A_2_A2_666.xxx";
$regex = "/[a-zA-Z]*-\d{4}-\d{2}-\d{2}_(\w)_(\d)_A2_(\d*)\.xxx$/";
global $replacements;
$replacements["K"] = "A";
$replacements["1"] = "2";
$replacements["383"] = "666";
$result = preg_replace_callback($regex, function($matches){
global $replacements;
print_r($matches);
// ended here. no way.
}, $filename);
if(strcmp($result,$expected)==0)
echo "preg_replace_callback() : Yep
";
else
echo "preg_replace_callback() : Nop
";
preg_match($regex, $filename, $matches, PREG_OFFSET_CAPTURE);
// remove useless global string match
array_shift($matches);
$result = $filename;
foreach($matches as $matchInfo){
$match = $matchInfo[0];
$position = $matchInfo[1];
$matchLength= strlen($match);
$beforeReplacementPart = substr($result, 0, $position);
$afterReplacementPart = substr($result, ($position + $matchLength));
$result = $beforeReplacementPart . $replacements[$match] . $afterReplacementPart;
}
if(strcmp($result,$expected)==0)
echo "preg_match() and substr game : Yep
";
else
echo "preg_match() and substr game : Nop
";