Jacobian
Jacobian

Reputation: 10802

preg_replace substring at particular position

I have values, which look like so:

Point_10_5_80_...
Point_22_21_77_...

Dots mean that pattern continues. Such values serve as templates in my code. And I want to be able to replace only second number in each template:

Point_10_5_80_... -> Point_10_777_80_...
Point_22_21_77_... -> Point_22_888_77_...

So, in first template 5 was replaced with 777 and in second template 21 was replaced with 888. I'm not sure how to implement this with preg_replace. I tried

$values = preg_replace('(Point_\d+_)(\d+)([_0-9]+)','$1' . $replacement . '$3', $template);

but in this case I just get empty values

Upvotes: 0

Views: 327

Answers (1)

Philipp Maurer
Philipp Maurer

Reputation: 2505

Your code has two errors: First of all you did not escape your pattern. To do so you can use slashes: $pattern = '/(Point_\d+_)\d+((?:_\d+)*)/' (The pattern is equivalent to your pattern, i just reformed it)

The other problem is, that your $replacement variable will contain a number itself. So by concatenating it with $1 and $2 you will get something like $1777$2. This is red as: Take group 17, add the number 77, then add group 2, which is not what you want. This is because there are a maximum of 100 groups (0 ~ 99) and it will always take two digits for the group identifier, if provided. To solve this prefix your groups with a 0: ' $01' . $replacement . '$02' to provide both digits. (It is not really necessary for group 2, because you do not add any number behind it.)

Your code then may look like this:

$array = ['Point_10_5_80_111','Point_22_21_77_222','Point_21_55_77_222'];
$replacements = [777, 888, 999];
$pattern = '/(Point_\d+_)\d+((?:_\d+)*)/';

$values = array_map(function($string, $replacement) use ($pattern) {
    return preg_replace($pattern, '$01' . $replacement . '$02', $string);
}, $array, $replacements);

Upvotes: 1

Related Questions