I have this code in php -:
function pregRepler($matches)
{
* do something
}
$str = preg_replace_callback($reg_exp,'pregRepler',$str);
When in function pregRepler, i would want to know the current match number like if it is the first match or the second or anything...
How do i do it.??
Try something like this:
function pregRepler($matches) {
static $matchcount = 0;
// do stuff
$matchcount++;
}
This works better with an anonymous function, as I mentioned in my answer to your other question, as this will avoid problems if you have multiple calls to preg_replace_callback.
You need to share a $count variable between both variable scopes, for example by using a variable alias:
$callback = function($matches) use (&$count) {
$count++;
return sprintf("<%d:%s>", $count, $matches[0]);
};
echo preg_replace_callback($pattern, $callback , $subject, $limit = -1, $count);
Before invoking, $count is equal to 0. After invoking $count is set to the number of replacements done. In between you can count up in your callback. You can also set to zero again when calling another time.
See it in action
See http://php.net/preg_replace_callback
$repled = 0;
function pregRepler($matches)
{
* do something
global $repled;
$repled++;
}
$str = preg_replace_callback($reg_exp,'pregRepler',$str);
Just count from a global variable.
Related
I have the function get_price_data(); which gives "0,11\u20ac" as return value.
The "0,11" is not static.
I want to do some maths with "0,11" from the string below.
My Code shown down below does not work how i want it to. Has someone any idea how i can complete this task ? I am very new to php.
<?php
function get_price_data() {
$json = file_get_contents("http://steamcommunity.com/market/priceoverview/?currency=3&appid=730&market_hash_name=Chroma%202%20Case");
$decode = json_decode($json,1);
echo $decode['median_price'];
}
$string=get_price_data();
$string2 = str_replace("\u20ac","",$string);
echo $string2 * 1000 - 120;
?>
<?php
function get_price_data() {
$json = file_get_contents("http://steamcommunity.com/market/priceoverview/?currency=3&appid=730&market_hash_name=Chroma%202%20Case");
$decode = json_decode($json,1);
return $decode['median_price']; // return here instead of echo.
}
You are somewhat correct that this return is necessary because this is a function. A return statement is not specifically required in a PHP function (functions will return null by default if there is no explicit return value.) The reason you need it to return is that you are using its returned value in this statement:
$string=get_price_data();
With echo instead of return, $string will be set to null here, and any subsequent operations on it will obviously not do what you intended.
If you change your function to return the value of $decode['median_price'], then $string=get_price_data(); will assign 0,11€ to $string, and then your replacements and calculations should work as expected.
$string=str_replace(array('€','\u20ac'),'',$string);
$string = str_replace(",",".",$string); // replace , with . as noted by mertizci
echo $string * 1000 - 120;
?>
Because of the comma in the changed price value, PHP cant do math things on it. You should change the comma with dot too.
Your code should be (edited):
<?php
$string=get_price_data();
$string=str_replace(array('€','\u20ac'),'',$string);
$string = str_replace(",",".",$string);
echo $string * 1000 - 120;
?>
I'm having some trouble figuring out how to make my function return a concatenated list of converted strings. The goal is to process 2 parallel arrays and use the value in one array ('U' or 'L') to cause the value (words) in the parallel array to convert to all upper or lower case, using a loop.
I want to return a concatenated list of the converted results.
I want no parameters to be used.
Right now it's just returning the first word, I'm not sure how to make it return the whole array of words. Any help is appreciated!
<?php
$case[0]='U'; // I just made these arrays up for the purpose of testing
$case[1]='L'; // the $case array values will be either U or L
$case[2]='U';
$case[3]='L';
$strings[0]='tHese'; // the $strings array values are words of varying case
$strings[1]='aRe';
$strings[2]='rAndoM';
$strings[3]='wOrDs';
function changeCase () {
global $case;
global $strings;
$total = "";
for ($i = 0; $i < sizeof($case); $i++) {
if ($case[$i] == "U") return strtoupper($strings[$i]);
elseif ($case[$i] == "L") return strtolower($strings[$i]);
$total = $total + $strings[$i]; //the returned value should look like THESEareRANDOMwords
}
return $total;
};
echo changeCase ();
?>
<?php
function changeCase ($case, $strings) {
$total = '';
foreach($case as $i=>$type)
$total .= ($type=='U') ? strtoupper($strings[$i]) : strtolower($strings[$i]);
return $total;
}
$case[0]='U'; // I just made these arrays up for the purpose of testing
$case[1]='L'; // the $case array values will be either U or L
$case[2]='U';
$case[3]='L';
$strings[0]='tHese'; // the $strings array values are words of varying case
$strings[1]='aRe';
$strings[2]='rAndoM';
$strings[3]='wOrDs';
echo changeCase($case, $strings);
You are using return in the loop, which will get you out of the function. You never reach the $total=... part.
array_map() is perfect for this.
$case[0]='U';
$case[1]='L';
$case[2]='U';
$case[3]='L';
$strings[0]='tHese';
$strings[1]='aRe';
$strings[2]='rAndoM';
$strings[3]='wOrDs';
// Set up an anonymous function to run on $case, and pass in $strings
$funct = function($value, $key) use ($strings) {
if($value == "U")
return strtoupper($strings[$key]);
else
return strtolower($strings[$key]);
};
// Pass in our keys as an additional parameter, this is not usual
// but in this case we need the keys to access the $strings array
$results = array_map($funct, $case, array_keys($case));
var_dump(implode("", $results));
I am trying to form an acronym from a given text. The Idea here is that the first Letter in $text ($text[0]) will be taken and placed inside the array $storage using array_push(). Now, if there is a space inside the array, the letter of the next index should be a part of the Acronym. I am currently not getting an ouput, what am I missing?
public function Acronym($text)
{
$text = str_split($text);
$count = strlen($text);
$storage = array();
for($i=0; $i<$count; $i++)
{
array_push($storage, $text[0]);
if($text[$i]==' ')
{
array_push($storage, $text[$i+1]);
}
foreach($storage as $clean)
{
echo $clean;
}
}
}
Your algorithm suffers from a few fatal flaws:
You're calling strlen() on an array, when you should be calling count():
$text = str_split($text);
$count = count($text);
However, you can index strings as arrays, so you don't need str_split() in this scenario, and you can keep $count = strlen( $text); by removing the call to str_split().
This should only happen once, so it should be outside the loop (This implies starting $i at 1):
array_push($storage, $text[0]);
Your foreach loop that prints the $storage array should be outside of the loop that is creating the acronym.
You can save the overhead of calling a function by using the shorthand array_push() notation. You should use array_push() when adding more than one element to an array. Otherwise, this will suffice:
$storage[] = $text[0];
You need to return something from your function, otherwise you won't be able to access anything outside of it.
Put that all together, and you get this:
public function Acronym($text)
{
$count = strlen( $text);
$storage[] = $text[0];
for( $i = 1; $i < $count; $i++)
{
if( $text[$i] == ' ')
{
$storage[] = $text[$i+1]);
$i++; // Can increment $i here because we know the next character isn't a space
}
}
foreach($storage as $clean)
{
echo $clean;
}
return $storage;
}
That being said, there are far better implementations for forming an acronym giving a string input. Here is one that I can think of:
public function Acronym( $text)
{
$acronym = array();
foreach( explode( ' ', $text) as $word)
{
$word = trim( $word);
$acronym[] = strtoupper( $word[0]);
}
return implode( '', $acronym);
}
Note that both functions will fail for inputs like Hello World. I am leaving it up to the OP to make these modifications (if necessary).
str_split turns the string into an array.
str_length brings the length of a string which you have overwritten with an array already. you need count()
You overwrite your first variable $text
$count = strlen($text);
In this line $text is an array, because you changed it in the first line of your method.
Try inverting the two first lines:
$count = strlen($text);
$text = str_split($text);
Note
This will solve your secondary problem, and enable your algorithm to run without errors. It doesn't fix your algorithm, but at least you will be able to debug it now.
you are running your loop on $count which is getting its value from str_len its an array because of return on $text = str_split($text);
So you have overwritten your $text variable you can fix it by changing order get length first then split.
I'm trying to template a document, I want to replace section of the document with dynamic text by searching a document for [%text%] and replacing it with $array['text'] or $text. I know I can use str_replace("[%text%]", $array['text'], $page), but I want to find all instances of [%(.*?)%] and replace with with $array[$1] instead of $1. I've tried using create_function($matches, $array), but it complains about Missing argument 2 for {closure}().
$page = preg_replace('#\[%(.*?)%\]#is', $array["$1"], $page);
You can preg_match_all('#[%(.*?)%]#is', $page, $matches); and then
if(count($matches == 2))
{
$key = 0;
foreach(array_unique($matches[0]) as $val)
{
if(isset($array[$key]))
{
$page = str_replace($val, $array[$key++], $page);
}
else
{
break; // more matches than array elements
}
}
}
First do a preg_match and find the matching names. Then craete the array with replacements for every found name. Then use preg_replace with the array as second argument, thereby replacing the names with the items from the array.
You can do it with preg_replace_callback.
<?php
$page = preg_replace_callback('#\[%(.*?)%\]#is',
function ($m){
GLOBAL $array;
return $array[$m[1]];
}
, $page);
?>
For string functions, I find myself doing this kind of thing a lot:
$string = trim($string);
I would like to easily have functions where I can pass the string by reference, so I can instead do function($string);.
I was thinking about writing wrappers for all the string functions I want to use, and prefix it with a special character, like so:
function _trim(&$string) {
trim($string);
}
function _str_replace($a, $b, &$string) {
str_replace($a, $b, $string);
}
But I wonder if there's a way that's easier than writing a wrapper for each function? (Has someone written this library already?)
For functions that can take only one argument (the string) like trim(), strtolower() etc, you could do something like this maybe...?
function modify_str (&$str, $funcName) {
if (function_exists($funcName)) $str = $funcName($str);
}
// So you can now do
modify_str($str, 'trim');
modify_str($str, 'strtolower');
...but to be perfectly honest, I cant really see the point - for one thing, you can't chain functions that take an argument by reference (i.e. you can't do trim(strtolower($str)))
I tend not to write $str = trim($str); very much, because I am probably going to use the result fairly immediately in some other operation. Instead of this:
$str = trim($str);
some_func($str, $someOtherVar);
I just do this:
some_func(trim($str), $someOtherVar);
And in the event that I need to do something like this:
$str = trim($str);
some_func($str, $someOtherVar);
another_func($str, $yetAnotherVar);
I would do this:
some_func($str = trim($str), $someOtherVar);
another_func($str, $yetAnotherVar);
...but whatever you are trying to do by doing any of the above, what you are effectively achieving is making your code less readable, and probably nothing else.
EDIT
After doing something completely unrelated today, I realised there is a way to chain functions and call it by reference:
function modify_str (&$str) {
$args = func_get_args();
for ($i = 1; isset($args[$i]); $i++) {
if (function_exists($funcName = $args[$i])) $str = $funcName($str);
}
}
// So you could do
modify_str($str,'trim','strtolower');
...but I still maintain this is not the way to go.
ANOTHER EDIT
You could pass to functions that uses multiple arguments by doing something like this (untested):
function modify_str (&$str) {
$str_identifier = '$$$'; // This identifies the argument where $str should be used
$ops = func_get_args();
for ($i = 1; isset($args[$i]); $i++) { // Loop functions to be applied
if (function_exists($ops[$i]['function'])) {
$args = array();
for ($j = 0; isset($ops[$i][$j]); $j++) { // Loop arguments for this function and build an argument list in PHP syntax
$args[] = ($ops[$i][$j] === $str_identifier) ? '$str' : "\$ops[\$i][$j]";
}
// eval() it (as if you had written it as straight PHP)
eval("\$str = {$ops[$i]['function']}(".implode(',',$args).");");
}
}
}
// So you can call it like this
modify_str($str,array('function'=>'str_replace','&','&','$$$'),array('function'=>'explode',"\n",'$$$'));
// ..which should have the same effect as
$str = explode("\n",str_replace('&','&',$str));
// As you can see, the not-by-reference way is is much shorter and more readable