How to Increment Count in the Replacement String When Using Preg_Replace

How to increment count in the replacement string when using preg_replace?

Use preg_replace_callback():

$count = 0;
preg_replace_callback('/test/', 'rep_count', $content);

function rep_count($matches) {
global $count;
return 'test' . $count++;
}

How can I find, increment and replace in php?

$new = preg_replace("/(\d+)_(\d+)/e", '"$1_" . ("$2" + 1)', $old);

The $1 etc terms are not actually variables, they are strings that preg_replace will interpret in the replacement text. So there is no way to do this using straight text-based preg_replace.

However, the /e modifier on the regular expression asks preg_replace to interpret the substitution as code, where the tokens $1 etc will actually be treated as variables. You supply the code as a string, and preg_replace will eval() it in the proper context, using its result as the replacement.

preg_replace() the same string by increment variable based on occurrences order

Just use preg_replace_callback(), so that it calls the anonymous function for every match which you get and then pass the variable $count by reference to keep track of the amount of matches, e.g.

<?php

$string = "figno some text and another figno then last figno";
$count = 1;
echo preg_replace_callback("/figno/s", function($m)use(&$count){
return $count++;
}, $string);

?>

output:

1 some text and another 2 then last 3

Replace substrings with an incremented counter value

$str = 'a hello a some a';
$i = 0;

while (strpos($str, 'a') !== false)
{
$str = preg_replace('/a/', $i++, $str, 1);
}

echo $str;

PHP preg_replace regex - sequentially increasing numbers in replacements

Here is your solution. Try this

<?php
$string = "Mary had a little lamb";
$count = 0;
$newstring = preg_replace_callback(
'/\S+/',
function($match) use (&$count) { return (( '(:word_' . $count++ . ':' .$match[0] . ':) ' )); },
$string
);
echo $newstring;
?>

PHP preg_replace_callback function is matching the regex pattern given as the first parameter with the $string given as its third parameter. you can also modify the regex pattern as per your need to match your required value. I also use $count as passing by reference to get the count of matched words.

Replacing occurrencies of element inside a string one by one adding an index

You can use preg_replace_callback and pass a counter into the anonmous function used as the replacement argument:

$text = "abc □□□ def □□□ ghi □□□";
$pattern = "/□□□/i";
$counter = 1;
echo preg_replace_callback($pattern, function($m) use (&$counter) {
return "hello" . $counter++;
}, $text);
// => abc hello1 def hello2 ghi hello3

See the PHP demo.

Note that the & in front of $counter makes it possible to update this variable value inside the replacement.

Is it possible to increment numbers using regex substitution?

This question's topic amused me for one particular implementation I did earlier. My solution happens to be two substitutions so I'll post it.

My implementation environment is solaris, full example:

echo "0 1 2 3 7 8 9 10 19 99 109 199 909 999 1099 1909" |
perl -pe 's/\b([0-9]+)\b/0$1~01234567890/g' |
perl -pe 's/\b0(?!9*~)|([0-9])(?=9*~[0-9]*?\1([0-9]))|~[0-9]*/$2/g'

1 2 3 4 8 9 10 11 20 100 110 200 910 1000 1100 1910

Pulling it apart for explanation:

s/\b([0-9]+)\b/0$1~01234567890/g

For each number (#) replace it with 0#~01234567890. The first 0 is in case rounding 9 to 10 is needed. The 01234567890 block is for incrementing. The example text for "9 10" is:

09~01234567890 010~01234567890

The individual pieces of the next regex can be described seperately, they are joined via pipes to reduce substitution count:

s/\b0(?!9*~)/$2/g

Select the "0" digit in front of all numbers that do not need rounding and discard it.

s/([0-9])(?=9*~[0-9]*?\1([0-9]))/$2/g

(?=) is positive lookahead, \1 is match group #1. So this means match all digits that are followed by 9s until the '~' mark then go to the lookup table and find the digit following this number. Replace with the next digit in the lookup table. Thus "09~" becomes "19~" then "10~" as the regex engine parses the number.

s/~[0-9]*/$2/g

This regex deletes the ~ lookup table.

Not incrementing variable in an anonymous callback function

You want to pass $i by reference, so it gets updated when you increment it with $i++:

$result = preg_replace_callback($pattern, function($matches) use (&$i, $replacement) {
return $replacement[$i++];
}, $str);

Notice the & before $i.

How to assign an ID to each replaced string in preg_replace and get a list of matched words

You could use preg_replace_callback() and pass the $counter reference to increment it :

$list = array("dumb", "stupid", "brainless");
$string = 'You are kind of dumb and brainless. Very dumb!';

// See comments below - Many thanks @revo
usort($list, function($a,$b) { return strlen($b) < strlen($b); });

$counter = 0 ; // Initialize the counter
$list_q = array_map('preg_quote', $list) ; // secure strings for RegExp

// Transform the string
$string = preg_replace_callback('~(' . implode('|',$list_q) . ')~',
function($matches) use (&$counter) {
$counter++;
return '<span id="bad_' . $counter . '">'
. substr($matches[0], 0, 1)
. str_repeat('.', strlen($matches[0]) - 1)
. '</span>' ;
}, $string);

echo $string;

Will outputs :

You are kind of <span id="bad_1">d...</span> and <span id="bad_2">b........</span>. Very <span id="bad_3">d...</span>!

Using a function, that stores the matches in $references variable :

function sanitize_badwords($string, &$references) {

static $counter ;
static $list ;
static $list_q ;

if (!isset($counter)) {
$counter = 0 ;
$list = array("dumb", "stupid", "brainless");

// See comments below - Many Thanks @revo
usort($list, function($a,$b) { return strlen($b)< strlen($b) ; });

$list_q = array_map('preg_quote', $list);
}

return preg_replace_callback('~('.implode('|',$list_q).')~',
function($matches) use (&$counter, &$references){
$counter++;
$references[$counter] = $matches[0];
return '<span id="bad_'.$counter.'">'
. substr($matches[0],0,1)
. str_repeat('.', strlen($matches[0])-1)
. '</span>' ;

}, $string) ;
}

$matches = [] ;
echo sanitize_badwords('You are kind of dumb and brainless. Very dumb!', $matches) ;

print_r($matches);

Will outputs :

You are kind of <span id="bad_1">d...</span> and <span id="bad_2">b........</span>. Very <span id="bad_3">d...</span>!

Array
(
[1] => dumb
[2] => brainless
[3] => dumb
)


Related Topics



Leave a reply



Submit