0

I have the following code:

$f = 'IMG_1474.PNG';
preg_replace('/(.*)([.][^.]+$)/', '$1' . time() . '$2', $f)

which should split the IMG_1474 and .PNG and add the epoch in between. The first capture group appears to be empty though.

If preg_match is used I can see the first capture group is not empty (so regex performs the same in PHP as on regex101).

preg_match('/(.*)([.][^.]+$)/', $f, $match);
print_r($match);

Functional demo: https://3v4l.org/VgDWJ (the 604147502 is the time() result)

My presumption is that something is happening with the concatenation on the replace bit.

user3783243
  • 4,418
  • 5
  • 14
  • 34

1 Answers1

0

In fact, the issue is the concatenation of the capture groups with time(). Use this version instead:

$f = 'IMG_1474.PNG';
$output = preg_replace('/(.*)([.][^.]+$)/', '${1}' . time() . '${2}', $f);
echo $output;

This prints:

IMG_14741604148316.PNG
        ^^^^^^^^^^  second since epoch (1970-01-01)

To understand why this is happening, we have to consider that variable substitution occurs before the preg_replace function call does. So your concatenated replacement term:

'$1' . time() . '$2'

actually first becomes:

'$1' . '1604148623' . '$2'

which is:

'$11604148623' . '$2'

The "first" capture group here is probably being interpreted as $11 (or $116, etc.), and is not defined. This is why you are currently only getting the second capture group, but the first one is empty. The solution I suggested uses ${1} which preserves the capture group reference so it is available during the preg_replace call as you intend.

Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
  • Oh, I see. I was incorrect in my statement `the 604147502 is the time() result` statement as well. The first integer of that was paired with my attempted capture group and lost because `$11` doesn't exist. Thanks. – user3783243 Oct 31 '20 at 12:51
  • 1
    @user3783243 ... and `$2` as you have it actually works, because nothing follows it. – Tim Biegeleisen Oct 31 '20 at 12:54