I've tried to use both preg_replace and preg_replace_callback maybe in a wrong way. What I do wrong?
$str = '/admin/companies/{company}/projects/{project}/photos/{photo}/delete';
$pattern = '/({\w+})/';
$replacement = ['str_1', 'str_2', 'str_3'];
$i = 0;
$result = preg_replace_callback($pattern, function($matches) use ($i, $replacement) {
return $replacement[$i++];
}, $str);
Current Output: /admin/companies/str_1/projects/str_1/photos/str_1/delete
Expected Output: /admin/companies/str_1/projects/str_2/photos/str_3/delete
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.
Related
$string = 'Hello [user=1]';
$bbc = array('/\[user=(.*?)\]/is');
$replace = array(user('textlink',$1));
$s = preg_replace($bbc , $replace, $string);
echo $s
How do I change $1 in preg_replace with a function?
If I understand you correctly, you want to execute user() function on each match? As mentioned in comments, use the preg_replace_callback() function.
<?php
$string = 'Hello [user=1]';
$s = preg_replace_callback(
'/\[user=(.*?)\]/is',
function($m) {return user('textlink', $m[1]);},
$string
);
echo $s;
You may use a preg_replace_callback_array:
$string = 'Hello [user=1]';
$bbc = array(
'/\[user=(.*?)\]/is' => function ($m) {
return user('textlink',$m[1]);
});
$s = preg_replace_callback_array($bbc, $string);
echo $s;
See PHP demo.
You may add up the patterns and callbacks to $bbc.
Is there any way I can replace one value and retrieve another in the same string in a more efficient way than in the code below, for example a method that combines preg_replace() and preg_match()?
$string = 'abc123';
$variable = '123';
$newString = preg_replace("/(abc)($variable)/",'$1$2xyz', $string);
preg_match("/(abc)($variable)/", $string, $matches);
$number = $matches[2];
You can use a single call to preg_replace_callback() and update the value of $number in the code of the callback function:
$string = 'abc123';
$variable = '123';
$number = NULL;
$newString = preg_replace_callback(
"/(abc)($variable)/",
function ($matches) use (& $number) {
$number = $matches[2];
return $matches[1].$matches[2].'xyz';
},
$string
);
I don't think there is a big speed improvement. The only advantage could be on the readability.
I have a regex to reformat a date from "dd/mm/yyyy HH:ii:ss" to YYYY-MM-DD HH:II:SS which is fine, but I would also use the same for validating date only (when no hours are provided).
Maybe there is a way to give default value to the replacement but I didn't found it.
$regex = '#^(\d{2})/(\d{2})/(\d{4})(?: (\d{2}):(\d{2})(?::(\d{2}))?)?$#';
$replace = '$3-$2-$1 $4:$5:00';
$str = '07/11/2013 20:30';
$val = preg_replace($regex, $replace, $str);
echo $val; // "2013-11-07 20:30:00"
$str = '07/11/2013';
$val = preg_replace($regex, $replace, $str);
echo $val; // "2013-11-07 ::00"
You can use preg_replace_callback and provide a custom callback method to perform the replacement. Inside you're callback, you can apply your default values:
$regex = '#^(\d{2})/(\d{2})/(\d{4})(?: (\d{2}):(\d{2})(?::(\d{2}))?)?$#';
$replace = function ($m) {
if (!$m[4]) $m[4] = '00';
if (!$m[5]) $m[5] = '00';
return "$m[3]-$m[2]-$m[1] $m[4]:$m[5]:00";
};
$str = '07/11/2013 20:30';
$val = preg_replace_callback($regex, $replace, $str);
echo $val; // "2013-11-07 20:30:00"
$str = '07/11/2013';
$val = preg_replace_callback($regex, $replace, $str);
echo $val; // "2013-11-07 00:00:00"
To validate date and time try this:
$regex = '(\d{2})/(\d{2})/(\d{4}) (\d{2}):(\d{2}):(\d{2})';
I am trying to find the word and add a number next to it. How could he do? I tried with the code below, but I could not. Could anyone help me?
Thank you!
$string = 'I220ABCD I220ABCDEF I220ABCDEFG'
if (preg_match("/I220.*/", $string, $matches)) {
echo $matches[0];
}
Expected result:
I220ABCD9
I220ABCDEF10
I220ABCDEFG11
Use preg_replace_callback instead like this:
$str = 'I220AB FRRRR CD I221ABCDEF I220AB DSFDSF CDEFG';
$repl= preg_replace_callback('~(I220[^\s]+)~', function($m) {
static $i=9;
return $m[1] . $i++;
}, $str);
echo $repl\n"; // I220AB9 FRRRR CD I221ABCDEF I220AB10 DSFDSF CDEFG
I dont know what your requirnments for adding the number at the end are so i just incremeneted during the loop;
$string = 'I220ABCD I220ABCDEF I220ABCDEFG';
$arrayStrings = explode(" ", $string);
$int = 9;
$newString = '';
foreach($arrayStrings as $stringItem)
{
if (preg_match("/I220.*/", $stringItem, $matches))
{
$stringItem = $stringItem.$int;
$newString = $newString.$stringItem." ";
$int++;
}
}
echo $newString;
Use preg_replace_callback():
$string = 'I220ABCD I220ABCDEF I220ABCDEFG';
// This requires PHP5.3+ since it's using an anonymous function
$result = preg_replace_callback('/I220[^\s]*/', function($match){
return($match[0].rand(0,10000)); // Add a random number between 0-10000
}, $string);
echo $result; // I220ABCD3863 I220ABCDEF5640 I220ABCDEFG989
Online demo.
You'll need to use a catch block in your regex e.g. "/I220([^ ]+)/" and if you want them all, you'll need to use preg_match_all, too.
preg_replace_callback with your needs:
$string = 'I220ABCD I220ABCDEF I220ABCDEFG';
class MyClass{
private static $i = 9;
private static function callback($matches){
return $matches[0] . self::$i++;
}
public static function replaceString($string){
return preg_replace_callback('/I220[^\s]+/',"self::callback",$string);
}
}
echo(MyClass::replaceString($string));
of course you can edit to class to initialize the way you want
function anchor($text)
{
return preg_replace('#\>\>([0-9]+)#','<span class=anchor>>>$1</span>', $text);
}
This piece of code is used to render page anchor.
I need to use the
([0-9]+)
part as a variable to do some maths to define the exact url for the href tag.
Thanks.
Use preg_replace_callback instead.
In php 5.3 +:
$matches = array();
$text = preg_replace_callback(
$pattern,
function($match) use (&$matches){
$matches[] = $match[1];
return '<span class=anchor><a href="#$1">'.$match[1].'</span>';
}
);
In php <5.3 :
global $matches;
$matches = array();
$text = preg_replace_callback(
$pattern,
create_function('$match','global $matches; $matches[] = $match[1]; return \'<span class=anchor><a href="#$1">\'.$match[1].\'</span>\';')
);