Php preg_replace_callback no work me - php

I try replace characters from string and put others , for this use preg_replace_callback function , the problem is this function change order of original text and show differents results
For example if the string it´s :
Hello everybody [1-2-3] this it´s one test [4-5-6-7-8] --- > ORIGINAL TEXT
The script search the [ ] and separate this content with [ ] from the other text , but show me as i put here :
1-2-3 4-5-6-7-8 Hello Everybody this it´s one test --- > BAD RESULT
When the right order it´s the first without [ ]
Hello everybody 1-2-3 this it´s one test 4-5-6-7-8
The script i create :
<?php
$text = " This is a test [gal~ruta~100~100] This is other test [gal~ruta2~100~100]";
function gal($matches)
{
global $text;
$exp=explode("~",$matches[1]);
$end=str_replace($matches[1],$a,$text);
if ($exp[0]=="gal")
{
$a="".$exp[1]."".$exp[2]."".$exp[3]."";
echo $a;
}
}
echo preg_replace_callback(
"/\[(.*?)\]/",
"gal",
$text);
?>
Thank´s everybody for the help

You need to return something from your callback, which will be substituted in the original string. You most certainly don't want to echo, which will send the values straight to the output, in order of execution.
However, it sounds like you don't even need a callback function to remove the brackets around your numbers.
$str = preg_replace("/\[(.*?)\]/", "$1", $str);
CodePad.

Related

PHP - Replace everything between String including content

I want to iterate over a string which looks like this.
Booo ahh [Hello] and what is [Baby] at your [Mouse]
My target is to replace every [###] with another string, which is not static, but can handle the content between the brackets.
Should be something like
function replace_string($text) {
...
//Maybe some kind of loop for all brackets
{
$content = ... //For example Hello, Baby, Mouse => ###
$replacement = "I'm a " . $content . "!";
...
}
return $replacedString;
}
I don't think it can work like in my "suggestion", but I hope I could show what I want to do and somebody can help me.
For what i understand, you want to have this string at the end:
Booo ahh [I'm a Hello!] and what is [I'm a Baby!] at your [I'm a Mouse!]
So you can use preg_replace function: http://php.net/manual/en/function.preg-replace.php
Your code will looks like:
function replace_string($text)
{
return preg_replace('/\[([^\]]+)\]+/', "[I'm a $1!]", $string);
}
so
<?php
$string = 'Booo ahh [Hello] and what is [Baby] at your [Mouse]';
echo replace_string($string);
// will display
// Booo ahh [I'm a Hello!] and what is [I'm a Baby!] at your [I'm a Mouse!]
not sure if you want to keep the brackets or not, if you don't, and want to have
Booo ahh I'm a Hello! and what is I'm a Baby! at your I'm a Mouse!
just use:
preg_replace('/\[([^\]]+)\]+/', "I'm a $1!", $string);
You can see the regex here: https://regex101.com/r/8hJQr0/1

PHP function Delete characters in string Between Tokens Unless Tokens Match a specific String

Ok so here is what I am trying to do, I need a php function that I can pass 4 parameters.
1) A String (Containing Tokens with text between them)
2) A Start Token String Parameter
3) A Stop Token String Parameter
4) A DO NOT DELETE String Parameter
I want to pass a (1)long string to the function and have it remove all the multiple instances of the (2)Start Tokens and all the Text Until The (3)Stop Token, UNLESS the (4)Do NOT DELETE Parameter is present in that part of the String.
The Setup would be like this:
HERE is the way the function would be setup:
function CleanUpMyString($string-1, $start-2, $end-3, $keep-4){
// Working Code That Does The Work Here
}
The String That I could Pass To The Function May Look Like this examples:
$stringTEST = "This is the intro of the string, <<<This Part Would Be Deleted>>> in the next snippet of the string, <<<we will delete another part>>> This is going pretty well. <<<keep>We do not delete this part because of the added token part 'keep>'.>>> We will add some more rambling text here. Then we will add another snippet. <<<We will also delete this one.>>><<<keep>But in the end it is all good!>>>";
Assuming I called the function like this:
echo CleanUpMyString($stringTEST, '<<<', '>>>', 'keep>');
I would get the following output:
This is the intro of the string, in the next snippet of the string, This is going pretty well. We do not delete this part because of the added token part 'keep>'. We will add some more rambling text here. Then we will add another snippet. But in the end it is all good!
I have no control over the input string, so the tokens could occur anywhere in any number, and there is not rational order in which they may appear.
I really am not sure where to start. I took a look at this thread:
PHP function to delete all between certain character(s) in string
which I thought has been the closest thing to what I wanted, but I could not see how to extend the idea to my application. Any help would be seriously appreciated!
my suggestion is to use preg_replace_callback
<?php
function CleanUpMyString($string, $start, $end, $keep)
{
return preg_replace_callback(
'~' . preg_quote($start, '~') . '.+?' . preg_quote($end, '~') . '~',
function ($M) use ($start, $end, $keep) {
if (strpos($M[0], $keep)) {
return str_replace([$start, $end, $keep], '', $M[0]);
} else {
return '';
}
},
$string
);
}
$stringTEST = "This is the intro of the string, <<<This Part Would Be Deleted>>> in the next snippet of the string, <<<we will delete another part>>> This is going pretty well. <<<keep>We do not delete this part because of the added token part 'keep>'.>>> We will add some more rambling text here. Then we will add another snippet. <<<We will also delete this one.>>><<<keep>But in the end it is all good!>>>";
echo CleanUpMyString($stringTEST, '<<<', '>>>', 'keep>');
Hope this will help you out, Here i am using preg_match to gather all matching tokens from start to end and then we are iterating over matches to keep required portion of string and removing un-necessary part.
Try this code snippet here
<?php
ini_set('display_errors', 1);
$stringTEST = "This is the intro of the string, <<<This Part Would Be Deleted>>> in the next snippet of the string, <<<we will delete another part>>> This is going pretty well. <<<keep>We do not delete this part because of the added token part 'keep>'.>>> We will add some more rambling text here. Then we will add another snippet. <<<We will also delete this one.>>><<<keep>But in the end it is all good!>>>";
echo CleanUpMyString($stringTEST, "<<<", ">>>", "keep>");
function CleanUpMyString($stringTEST, $start, $end, $keep)
{
$startQuotes= preg_quote($start);
$endQuotes= preg_quote($end);
preg_match_all("/$startQuotes.*?(?:$endQuotes)/", $stringTEST,$matches);
foreach($matches[0] as $key => $value)
{
if(stristr($value, $start.$keep)!==false)
{
$stringTEST= substr_replace($stringTEST,"",strpos($stringTEST, $start.$keep), strlen($start.$keep));;
$stringTEST= substr_replace($stringTEST,"",strpos($stringTEST, $end), strlen($end));
}
else
{
$stringTEST= str_replace($value, "", $stringTEST);
}
}
return $stringTEST;
}

preg replace with method inside it

echo preg_replace("#\[map\](.+)\[\/map\]#e", '[link=maps.php/".$map_id[array_search("$1", $map_name)]."/$1/]$1[/link]', $text);
is my try.
I want to replace
[map]map_name[/map]
to
[link]maps.php/id/map_name[/link]
I have two arrays, $map_id and $map_name. They contain the exact same items and items are connected with the same key, eg: $map_id[123] that ID is for that map: $map_name[123].
My preg_replace does not work as it returns: Failed evaluating code: [link=maps.php/".in_array("ksz_luminous", $map_name)."/ksz_luminous/]ksz_luminous[/link]
You should not use the e flag. Suppose I used this:
[map]",array())].shell_exec("evil command of evil").$map_id[array_search("[/map]
Or something like that.
Anyway, try this:
echo preg_replace_callback("(\[map\](.+?)\[/map\])i",
function($m) use ($map_id,$map_name) {
return "[link=maps.php/"
.$map_id[array_search($m[1], $map_name)]
."/".$m[1]."/]".$m[1]."[/link]";
}, $text);

PHP preg_replace problem

This is a follow-up question to the one I posted here (thanks to mario)
Ok, so I have a preg_replace statement to replace a url string with sometext, insert a value from a query string (using $_GET["size"]) and insert a value from a associative array (using $fruitArray["$1"] back reference.)
Input url string would be:
http://mysite.com/script.php?fruit=apple
Output string should be:
http://mysite.com/small/sometext/green/
The PHP I have is as follows:
$result = preg_replace('|http://www.mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|e', ' "http://www.mysite.com/" .$_GET["size"]. "/sometext/" .$fruitArray["$1"]. "/"', $result);
This codes outputs the following string:
http://mysite.com/small/sometext//
The code seems to skip the value in $fruitArray["$1"].
What am I missing?
Thanks!
Well, weird thing.
Your code work's perfectly fine for me (see below code that I used for testing locally).
I did however fix 2 things with your regex:
Don't use | as a delimiter, it has meaning in regex.
Your regular expression is only giving the illusion that it works as you're not escaping the .s. It would actually match http://www#mysite%com/script*php?fruit=apple too.
Test script:
$fruitArray = array('apple' => 'green');
$_GET = array('size' => 'small');
$result = 'http://www.mysite.com/script.php?fruit=apple';
$result = preg_replace('#http://www\.mysite\.com/script\.php\?fruit=([a-zA-Z0-9_-]*)#e', ' "http://www.mysite.com/" .$_GET["size"]. "/sometext/" .$fruitArray["$1"]. "/"', $result);
echo $result;
Output:
Rudis-Mac-Pro:~ rudi$ php tmp.php
http://www.mysite.com/small/sometext/green/
The only thing this leads me to think is that $fruitArray is not setup correctly for you.
By the way, I think this may be more appropriate, as it will give you more flexibility in the future, better syntax highlighting and make more sense than using the e modifier for the evil() function to be internally called by PHP ;-) It's also a lot cleaner to read, IMO.
$result = preg_replace_callback('#http://www\.mysite\.com/script\.php\?fruit=([a-zA-Z0-9_-]*)#', function($matches) {
global $fruitArray;
return 'http://www.mysite.com/' . $_GET['size'] . '/sometext/' . $fruitArray[$matches[1]] . '/';
}, $result);
i write it again, i don't understand good where is the error, the evaluation of preg results is very weird in php
preg_replace(
'|http\://([\w\.-]+?)/script\.php\?fruit=([\w_-]+)|e'
, '"http://www.$1/".$_GET["size"]."/sometext/".$fruitArray["$2"]."/";'
, $result
);
It looks like you have forgotten to escape the ?. It should be /script.php\?, with a \? to escape properly, as in the linked answer you provided.
$fruitArray["\$1"] instead of $fruitArray["$1"]

How to create a Wordpress shortcode-style function in PHP

I am trying to create a Wordpress shortcode-style feature in PHP to replace shortcodes like "[[133]]" with images. Basically, I have a MySQL table of image URLs/titles/subtitles with IDs 1-150, and I want to be able to dynamically insert them into the text of my pages with shortcodes like this:
Blabla bla bla bla bla. [[5]] Also, bla bla bla bla bla [[27]]
Hey, and bla bla bla! [[129]]
So, I just want to grab the ID as $id, and then feed it to a MySQL query like
mysql_query("SELECT title,subtitle,url FROM images WHERE id = $id")
and then replace the "[[id]]" with the img/title/subtitle. I would like to be able to do this multiple times on the same page.
I know this has to involve regex and some combination of preg_match, preg_replace, strstr, strpos, substr... but I don't know where to start and which functions I should be using to do which things. Can you recommend a strategy? I don't need the code itself—just knowing what to use for which parts would be extremely helpful.
If you want to be able to write shortcodes like this :
[[function_name_suffix parameter1 parameter2 ...]]
here is a more complete way, using preg_replace_callback and call_user_func_array to implement parameterized shortcodes.
function shortcodify($string){
return preg_replace_callback('#\[\[(.*?)\]\]#', function ($matches) {
$whitespace_explode = explode(" ", $matches[1]);
$fnName = 'shortcode_'.array_shift($whitespace_explode);
return function_exists($fnName) ? call_user_func_array($fnName,$whitespace_explode) : $matches[0];
}, $string);
}
If this function is defined :
function shortcode_name($firstname="",$lastname=""){
return "<span class='firstname'>".$firstname."</span> <span class='lastname'>".$lastname."</span>";
}
Then this call
print shortcodify("My name is [[name armel larcier]]");
Will output :
My name is <span class='firstname'>armel</span> <span class='lastname'>larcier</span>
This is just something I implemented right now based on supertrue's idea.
Any feedback is more than welcome.
With a function getimage($id) that does the MySQL query and formats the replacement text, this almost does everything you need:
$text = "Blabla [[5]] and [[111]] bla bla bla [[27]] and bla bla bla! [[129]]";
$zpreg = preg_match_all('#\[\[(\d{1,3})\]\]#', $text, $matches );
var_dump( $matches[1] );
$newtext = preg_replace('#\[\[(\d{1,3})\]\]#', getimage($matches[1][?????]), $text);
echo $newtext;
I just need to figure out what to put inside getimage() (where ????? is) that will make it put in the right image for the right [[id]].
Refer preg_match_all and preg_replace on official documentation for more details.
Various different approaches can be taken for this, depending on how you plan to display ect,
Take the sentence "Hello [34] world"
Create a simple function e.g replaceCode($string)
function replaceCode($string){
$pos = strpos($string, '['); // Find the first occurrence of the bracket
if($pos != false){
// If everything is ok take the next 2 numbers from it
// Check for a close bracket & remove ]
// call another function to replace the number with the image text
}
}
If anymore occurrences of brackets are found, recursively call the function again, passing the rest of the string to the function again.
Note: Validation may need to be done first to ensure the [ and ] are properly balanced!
My bet is PHP's strtr function...
<?php
function get_profile_image($image_url){
return "<img src='{$image_url}' height='200px' width='200px' />";
}
$trans = array(
"[[1]]" => "Vishal",
"[[2]]" => "Kumar",
"[[3]]" => "Sahu",
"[[4]]" => "Web Designer",
"[[5]]" => "Draw and Paint",
"[[6]]" => ucwords("any programming language"),
"[[7]]" => strtoupper("PHP, JAVASCRIPT and HTML"),
"[[8]]" => get_profile_image("http://php.net/images/logos/php-logo.svg"),
"[[9]]" => "http://php.net/images/logos/php-logo.svg"
);
$str = <<<HEREDOC_1
[[8]]
<pre>My name is [[1]] [[2]] [[3]].
I am a [[4]] and I love to [[5]].
I don't know [[6]] but I know [[7]] little bit.</pre>
Here is my profile image <img src='[[9]]' alt='[[1]]-[[2]]-[[3]]-[[4]]' />
HEREDOC_1;
echo strtr($str, $trans);
it's output is
[http://php.net/images/logos/php-logo.svg] My name is Vishal Kumar
Sahu. I am a Web Designer and I love to Draw and Paint. I don't know
Any Programming Language but I know PHP, JAVASCRIPT AND HTML little
bit. Here is my profile image [Vishal-Kumar-Sahu-Web Designer]
It is working fine on 5.6.
The regex, I believe, would be:
/\[\[[1-9]{1,3}\]\]/g
(for a 1-to-3 digit number inside double brackets.)

Categories