In few words, I am trying to replace all the "?" with the value inside a variable and it doesn't work. Please help.
$string = "? are red ? are blue";
$count = 1;
update_query($string, array($v = 'violets', $r = 'roses'));
function update_query($string, $values){
foreach ( $values as $val ){
str_replace('?', $val, $string, $count);
}
echo $string;
}
The output I am getting is: ? are red ? are blue
Frustrated by people not paying attention, I am compelled to answer the question properly.
str_replace will replace ALL instances of the search string. So after violets, there will be nothing left for roses to replace.
Sadly str_replace does not come with a limit parameter, but preg_replace does. But you can actually do better still with preg_replace_callback, like so:
function update_query($string, $values){
$result = preg_replace_callback('/\?/', function($_) use (&$values) {
return array_shift($values);
}, $string);
echo $string;
}
You forgot to set it equal to your variable.
$string = str_replace('?', $val, $string, $count);
You probably want to capture the return from str_replace in a new string and echo it for each replacement, and pass $count by reference.
foreach ( $values as $val ){
$newString = str_replace('?', $val, $string, &$count);
echo $newString;
}
This is the best and cleanest way to do it
<?php
$string = "? are red ? are blue";
$string = str_replace('?','%s', $string);
$data = array('violets','roses');
$string = vsprintf($string, $data);
echo $string;
Your code edited
$string = "? are red ? are blue";
update_query($string, array('violets','roses'));
function update_query($string, $values){
$string = str_replace('?','%s', $string);
$string = vsprintf($string, $values);
echo $string;
}
Ok guys here is the solution from a combination of some good posts.
$string = "? are red ? are blue";
update_query($string, array($v = 'violets', $r = 'roses'));
function update_query($string, $values){
foreach ( $values as $val ){
$string = preg_replace('/\?/', $val, $string, 1);
}
echo $string;
}
As mentioned, preg_replace will allow limiting the amount of matches to update. Thank you all.
You can solve this in two ways:
1) Substitute the question marks with their respective values. There are a hundred ways one could tackle it, but for something like this I prefer just doing it the old-fashioned way: Find the question marks and replace them with the new values one by one. If the values in $arr contain question marks themselves then they will be ignored.
function update_query($str, array $arr) {
$offset = 0;
foreach ($arr as $newVal) {
$mark = strpos($str, '?', $offset);
if ($mark !== false) {
$str = substr($str, 0, $mark).$newVal.substr($str, $mark+1);
$offset = $mark + (strlen($newVal) - 1);
}
}
return $str;
}
$string = "? are red ? are blue";
$vars = array('violets', 'roses');
echo update_query($string, $vars);
2) Or you can make it easy on yourself and use unique identifiers. This makes your code easier to understand, and more predictable and robust.
function update_query($str, array $arr) {
return strtr($str, $arr);
}
echo update_query(':flower1 are red :flower2 are blue', array(
':flower1' => 'violets',
':flower2' => 'roses',
));
You could even just use strtr(), but wrapping it in a function that you can more easily remember (and which makes sense in your code) will also work.
Oh, and if you are planning on using this for creating an SQL query then you should reconsider. Use your database driver's prepared statements instead.
Related
I have a variable $var and it contain comma separated value.
$var = 'the_ring,hangover,wonder_woman';
I want to make it like below.
$var = 'The Ring,Hangover,Wonder Woman';
I tried $parts = explode(',', $var); also I tried strpos() and stripos() but not able to figure it out.
What can I do to achieve this?
$var = 'the_ring,hangover,wonder_woman';
$list = explode(',', $var);
$list = array_map( function($name){
return ucwords(str_replace('_',' ', $name));
}, $list);
Returns:
Array
(
[0] => The Ring
[1] => Hangover
[2] => Wonder Woman
)
Imploding:
$imploded = implode(',', $list);
Returns:
'The Ring,Hangover,Wonder Woman'
You can use array_walk to do your replace and uppercase:
$var = 'the_ring,hangover,wonder_woman';
$parts = explode(',', $var);
array_walk($parts, function(&$item){
$item = str_replace('_', ' ', $item);
$item = ucwords($item);
});
$var = implode(',', $parts);
Using str_replace() function click here to explain
like this code
$str= 'the_ring,hangover,wonder_woman';
echo str_replace("_"," ","$str");
This is how you replace _ with white spaces using str_replace() function
$var = 'the_ring,hangover,wonder_woman';
echo str_replace("_"," ",$var);
$var = 'the_ring,hangover,wonder_woman';
$var1 = explode(',' $var);
foreach ($var1 as $key => $value) {
$var1[$key]=str_replace("_"," ",$value);
$var1[$key]=ucwords($var1[$key]);
}
$var = implode(',', $var1);
1.use str_replace to replace something in the string. In your case _ is replaced with space
2.use ucFirst method to capitalize every first character in the strings
$replaced = str_replace('_', ' ', $var);
$changed = ucfirst($replaced);
I looked up some reference like this question and this question but could not figure out what I need to do.
What I am trying to do is:
Say, I have two strings:
$str1 = "link/usa";
$str2 = "link/{country}";
Now I want to check if this the pattern matches. If they match, I want the value of country to be set usa.
$country = "usa";
I also want it to work in cases like:
$str1 = "link/usa/texas";
$str2 = "link/{country}/{place}";
Maybe integers as well. Like match every braces and provide the variable with value. (And, yes better performance if possible)
I cannot get a work around since I am very new to regular expresssions. Thanks in advance.
It will give you results as expected
$str1 = "link/usa";
$str2 = "link/{country}";
if(preg_match('~link/([a-z]+)~i', $str1, $matches1) && preg_match('~link/{([a-z]+)}~i', $str2, $matches2)){
$$matches2[1] = $matches1[1];
echo $country;
}
Note: Above code will just parse alphabets, you can extend characters in range as per need.
UPDATE:
You can also do it using explode, see example below:
$val1 = explode('/', $str1);
$val2 = explode('/', $str2);
${rtrim(ltrim($val2[1],'{'), '}')} = $val1[1];
echo $country;
UPDATE 2
$str1 = "link/usa/texas/2/";
$str2 = "/link/{country}/{city}/{page}";
if(preg_match_all('~/([a-z0-9]+)~i', $str1, $matches1) && preg_match_all('~{([a-z]+)}~i', $str2, $matches2)){
foreach($matches2[1] as $key => $matches){
$$matches = $matches1[1][$key];
}
echo $country;
echo '<br>';
echo $city;
echo '<br>';
echo $page;
}
I don't see the point to use the key as variable name when you can built an associative array that will be probably more handy to use later and that avoids to write ugly dynamic variable names ${the_name_of_the_var_${of_my_var_${of_your_var}}}:
$str1 = "link/usa/texas";
$str2 = "link/{country}/{place}";
function combine($pattern, $values) {
$keys = array_map(function ($i) { return trim($i, '{}'); },
explode('/', $pattern));
$values = explode('/', $values);
if (array_shift($keys) == array_shift($values) && count($keys) &&
count($keys) == count($values))
return array_combine($keys, $values);
else throw new Exception ("invalid format");
}
print_r(combine($str2, $str1));
I have a string that looks like this "thing aaaa" and I'm using explode() to split the string into an array containing all the words that are separated by space. I execute something like this explode (" ", $string) .
I'm not sure why but the result is : ["thing","","","","aaaa"]; Does anyone have an idea why I get the three empty arrays in there ?
EDIT : This is the function that I'm using that in :
public function query_databases() {
$arguments_count = func_num_args();
$status = [];
$results = [];
$split =[];
if ($arguments_count > 0) {
$arguments = func_get_args();
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arguments));
foreach ($iterator as $key => $value) {
array_push($results, trim($value));
}
unset($value);
$filtered = $this->array_unique_values($results, "String");
foreach ($filtered as $key => $string) {
if (preg_match('/\s/',$string)) {
array_push($split, preg_split("/\s/", $string));
} else {
array_push($split, $string);
}
}
unset($string);
echo "Terms : ".json_encode($split)."<br>";
foreach ($filtered as $database) {
echo "Terms : ".json_encode()."<br>";
$_action = $this->get_database($database);
echo "Action : ".json_encode($_action)."<br>";
}
unset($database);
} else {
return "[ Databases | Query Databases [ Missing Arguments ] ]";
}
}
It might be something else that messes up the result ?!
If you are looking to create an array by spaces, you might want to consider preg_split:
preg_split("/\s+/","thing aaaa");
which gives you array ("thing","aaaa");
Taken from here.
try this:
$str = str_replace(" ", ",", $string);
explode(",",$str);
This way you can see if it is just the whitespace giving you the problem if you output 4 commas, it's because you have 4 whitespaces.
As #Barmar said, my trim() just removes all the space before and after the words, so that is why I had more values in the array than I should have had.
I found that this little snippet : preg_replace( '/\s+/', ' ', $value ) ; replacing my trim() would fix it :)
$restricted_images = array(
"http://api.tweetmeme.com/imagebutton.gif",
"http://stats.wordpress.com",
"http://entrepreneur.com.feedsportal.com/",
"http://feedads.g.doubleclick.net"
);
This are the list of images that I want to know if a certain string has that kind of string.
For example:
$string = "http://api.tweetmeme.com/imagebutton.gif/elson/test/1231adfa/".
Since "http://api.tweetmeme.com/imagebutton.gif" is in the $restricted_images array and it is also a string inside the variable $string, it will replace the $string variable into just a word "replace".
Do you have any idea how to do that one? I'm not a master of RegEx, so any help would be greatly appreciated and rewarded!
Thanks!
why regex?
$restricted_images = array(
"http://api.tweetmeme.com/imagebutton.gif",
"http://stats.wordpress.com",
"http://entrepreneur.com.feedsportal.com/",
"http://feedads.g.doubleclick.net"
);
$string = "http://api.tweetmeme.com/imagebutton.gif/elson/test/1231adfa/";
$restrict = false;
foreach($restricted_images as $restricted_image){
if(strpos($string,$restricted_image)>-1){
$restrict = true;
break;
}
}
if($restrict) $string = "replace";
maybe this can help
foreach ($restricted_images as $key => $value) {
if (strpos($string, $value) >= 0){
$string = 'replace';
}
}
You don't really need regex because you're looking for direct string matches.
You can try this:
foreach ($restricted_images as $url) // Iterate through each restricted URL.
{
if (strpos($string, $url) !== false) // See if the restricted URL substring exists in the string you're trying to check.
{
$string = 'replace'; // Reset the value of variable $string.
}
}
You don't have to use regex'es for this.
$test = "http://api.tweetmeme.com/imagebutton.gif/elson/test/1231adfa/";
foreach($restricted_images as $restricted) {
if (substr_count($test, $restricted)) {
$test = 'FORBIDDEN';
}
}
// Prepare the $restricted_images array for use by preg_replace()
$func = function($value)
{
return '/'.preg_quote($value).'/';
}
$restricted_images = array_map($func, $restricted_images);
$string = preg_replace($restricted_images, 'replace', $string);
Edit:
If you decide that you don't need to use regular expressions (which is not really needed with your example), here's a better example then all of those foreach() answers:
$string = str_replace($restricted_images, 'replace', $string);
I have a string that contains elements from array.
$str = '[some][string]';
$array = array();
How can I get the value of $array['some']['string'] using $str?
This will work for any number of keys:
$keys = explode('][', substr($str, 1, -1));
$value = $array;
foreach($keys as $key)
$value = $value[$key];
echo $value
You can do so by using eval, don't know if your comfortable with it:
$array['some']['string'] = 'test';
$str = '[some][string]';
$code = sprintf('return $array%s;', str_replace(array('[',']'), array('[\'', '\']'), $str));
$value = eval($code);
echo $value; # test
However eval is not always the right tool because well, it shows most often that you have a design flaw when you need to use it.
Another example if you need to write access to the array item, you can do the following:
$array['some']['string'] = 'test';
$str = '[some][string]';
$path = explode('][', substr($str, 1, -1));
$value = &$array;
foreach($path as $segment)
{
$value = &$value[$segment];
}
echo $value;
$value = 'changed';
print_r($array);
This is actually the same principle as in Eric's answer but referencing the variable.
// trim the start and end brackets
$str = trim($str, '[]');
// explode the keys into an array
$keys = explode('][', $str);
// reference the array using the stored keys
$value = $array[$keys[0][$keys[1]];
I think regexp should do the trick better:
$array['some']['string'] = 'test';
$str = '[some][string]';
if (preg_match('/\[(?<key1>\w+)\]\[(?<key2>\w+)\]/', $str, $keys))
{
if (isset($array[$keys['key1']][$keys['key2']]))
echo $array[$keys['key1']][$keys['key2']]; // do what you need
}
But I would think twice before dealing with arrays your way :D