I'm trying to run a simple replacement on some input data that could be described as follows:
- take a regular expression
- take an input data stream
- on every match, replace the match through a callback
Unfortunately, preg_replace_callback() doesn't work as I'd expect. It gives me all the matches on the entire line, not individual matches. So I need to put the line together again after replacement, but I don't have the information to do that. Case in point:
<?php
echo replace("/^\d+,(.*),(.*),.*$/", "12,LOWERME,ANDME,ButNotMe")."
";
echo replace("/^\d+-\d+-(.*) .* (.*)$/", "13-007-THISLOWER ThisNot THISAGAIN")."
";
function replace($pattern, $data) {
return preg_replace_callback(
$pattern,
function($match) {
return strtolower($match[0]);
}, $data
);
}
https://www.tehplayground.com/hE1ZBuJNtFiHbdHO
gives me 12,lowerme,andme,butnotme
, but I want 12,lowerme,andme,ButNotMe
.
I know using $match[0] is wrong. It's just to illustrate here. Inside the closure I need to run something like
foreach ($match as $m) { /* do something */ }
But as I said, I have no information about the position of the matches in the input string which makes it impossible to put the string together again.
I've digged through the PHP documentation as well as several searches and couldn't find a solution.
Clarifications:
I know that $match[1], $match[2]... etc contain the matches. But only a string, not a position. Imagine in my example the final string is also ANDME instead of ButNotMe - according to the regex, it should not be matched and the callback should not be applied to it. That's why I'm using regexes in the first place instead of string replacements.
Also, the reason I'm using capture groups this way is that I need the replacement process to be configurable. So I cannot hardcode something like "replace #1 and #2 but not #3". On a different input file, the positions might be different, or there might be more replacements needed, and only the regex used should change.
So if my input is "15,LOWER,ME,NotThis,AND,ME,AGAIN"
, I want to be able to just change the regex, not the code and get the desired result. Basically, both $pattern and $data are variable.