I have a string in PHP that is a URI with all arguments:
$string = http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0
I want to completely remove an argument and return the remain string. For example I want to remove arg3 and end up with:
$string = http://domain.com/php/doc.php?arg1=0&arg2=1
I will always want to remove the same argument (arg3), and it may or not be the last argument.
Thoughts?
EDIT: there might be a bunch of wierd characters in arg3 so my prefered way to do this (in essence) would be:
$newstring = remove $_GET["arg3"] from $string;
There's no real reason to use regexes here, you can use string and array functions instead.
You can explode the part after the ? (which you can get using substr to get a substring and strrpos to get the position of the last ?) into an array, and use unset to remove arg3, and then join to put the string back together.:
$string = "http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0";
$pos = strrpos($string, "?"); // get the position of the last ? in the string
$query_string_parts = array();
foreach (explode("&", substr($string, $pos + 1)) as $q)
{
list($key, $val) = explode("=", $q);
if ($key != "arg3")
{
// keep track of the parts that don't have arg3 as the key
$query_string_parts[] = "$key=$val";
}
}
// rebuild the string
$result = substr($string, 0, $pos + 1) . join($query_string_parts);
See it in action at http://www.ideone.com/PrO0a
preg_replace("arg3=[^&]*(&|$)", "", $string)
I'm assuming the url itself won't contain arg3= here, which in a sane world should be a safe assumption.
$new = preg_replace('/&arg3=[^&]*/', '', $string);
This should also work, taking into account, for example, page anchors (#) and at least some of those "weird characters" you mention but don't seem worried about:
function remove_query_part($url, $term)
{
$query_str = parse_url($url, PHP_URL_QUERY);
if ($frag = parse_url($url, PHP_URL_FRAGMENT)) {
$frag = '#' . $frag;
}
parse_str($query_str, $query_arr);
unset($query_arr[$term]);
$new = '?' . http_build_query($query_arr) . $frag;
return str_replace(strstr($url, '?'), $new, $url);
}
Demo:
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0';
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1';
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0#frag';
$string[] = 'http://domain.com/php/doc.php?arg1=0&arg2=1&arg3=0&arg4=4';
$string[] = 'http://domain.com/php/doc.php';
$string[] = 'http://domain.com/php/doc.php#frag';
$string[] = 'http://example.com?arg1=question?mark&arg2=equal=sign&arg3=hello';
foreach ($string as $str) {
echo remove_query_part($str, 'arg3') . "\n";
}
Output:
http://domain.com/php/doc.php?arg1=0&arg2=1
http://domain.com/php/doc.php?arg1=0&arg2=1
http://domain.com/php/doc.php?arg1=0&arg2=1#frag
http://domain.com/php/doc.php?arg1=0&arg2=1&arg4=4
http://domain.com/php/doc.php
http://domain.com/php/doc.php#frag
http://example.com?arg1=question%3Fmark&arg2=equal%3Dsign
Tested only as shown.
Related
I've been working with this code
<?php
class PerchTemplateFilter_sol_en_cat_path extends PerchTemplateFilter {
public function filterAfterProcessing($value, $valueIsMarkup = false) {
// ORIGINAL STRING: solutions-en/rail-technologies/track-components/name-of-product
$mystring = $value;
$replace = ['solutions-en', '%2F'];
$str = '';
$oldstr = str_replace($replace, $str, $mystring);
$str_to_insert = 'XXX';
$findme = '/';
$pos = strpos($mystring, $findme); // I NEED THIS TO INSERT $str_to_insert AFTER THE SECOND FORWARD SLASH FOUND IN THE ORIGINAL STRING?
$value = substr_replace($oldstr, $str_to_insert, $pos, 0);
return $value;
// $value: /rail-technologies/track-components/XXX/name-of-product
// Insert string at specified position
// https://stackoverflow.com/questions/8251426/insert-string-at-specified-position
}
}
PerchSystem::register_template_filter('sol_en_cat_path', 'PerchTemplateFilter_sol_en_cat_path');
?>
My string is: solutions-en/rail-technologies/track-components/name-of-product
I want to end up with: /rail-technologies/XXX/track-components/name-of-product
XXX is only a placeholder value
I guess I need to do something with $pos to set where I want XXX to be added to the string.
I need to insert after the second forward slash, as the string may contain different text
The code above outputs this string: /rail-technoXXXlogies/track-components/ewosr-switch-lock
I can't seem to figure out how to insert XXX after the second forward slash.
Hope someone can provide some help.
How about explode to array, then implode the first two items.
Join with xxx and implode the rest?
function AddInTheMiddle($start, $where, $what){
$arr = explode("/", $what);
$str = implode("/", array_splice($arr,$start,$where)) . '/xxx/' . implode("/", $arr);;
return $str;
}
$str = 'solutions-en/rail-technologies/track-components/name-of-product';
$str = AddInTheMiddle(1, 2, $str);
https://3v4l.org/m98io
Thank you Andreas, your post gave me the nudge I needed. I did this in the end.
// ORIGINAL $value: solutions-en/rail-technologies/track-components/name-of-product
$str = explode("/", $value);
$value = $str[1] . '/' . 'solutions' . '/' . $str[2] . '/';
return $value;
// Removed: solutions-en
// Added: solutions
// $value: rail-technologies/solutions/track-components/name-of-product
I was able to add the name-of-product to the end of the new string elsewhere in my template.
I have a string example
this-is-the-example/exa
I want to trim /exa from the above line
$string1 = "this-is-the-example/exa";
$string2 = "/exa";
I am using rtrim($string1, $sting2)
But the output is this-is-the-exampl
I want to this-is-the-example as output.
Both string are dynamic and may have multiple occurrences within the string. But I only want to remove the last part. Also its not compulsory that the string2 has / in it. this may be normal string too. like a, abc too..
There are various approaches you can use for this:
With substr(DEMO):
function removeFromEnd($haystack, $needle)
{
$length = strlen($needle);
if(substr($haystack, -$length) === $needle)
{
$haystack = substr($haystack, 0, -$length);
}
return $haystack;
}
$trim = '/exa';
$str = 'this-is-the-example/exa';
var_dump(removeFromEnd($str, $trim));
With regex(DEMO):
$trim = '/exa';
$str = 'this-is-the-example/exa';
function removeFromEnd($haystack, $needle)
{
$needle = preg_quote($needle, '/');
$haystack = preg_replace("/$needle$/", '', $haystack);
return $haystack;
}
var_dump(removeFromEnd($str, $trim));
First explode the string, remove last element from exploded array using array_pop, then implode it back again with /.
$str = "this-is-the-example/exa";
if(strpos($str, '/') !== false)
{
$arr = explode('/', $str);
array_pop($arr);
$str = implode('/', $arr);
// output this-is-the-example
}
This will work event if you have multiple / in the URL and will remove last element only.
$str = "this-is-the-example/somevalue/exa";
if(strpos($str, '/') !== false)
{
$arr = explode('/', $str);
array_pop($arr);
$str = implode('/', $arr);
// output this-is-the-example
}
Say hi to strstr()
$str = 'this-is-the-example/exa';
$trim = '/exa';
$result = strstr($str, $trim, true);
echo $result;
You can use explode
<?php
$x = "this-is-the-example/exa";
$y = explode('/', $x);
echo $y[0];
the second parameter of rtrim is a character mask and not a string, your last "e" is trimed and that's normal.
COnsider using something else, regexp for example (preg_replace) to fit your needs
This keeps everything before "/" char :
$str = preg_replace('/^([^\/]*).*/','$1', 'this-is-the-example/exa');
This removes the last part.
$str = preg_replace('/^(.*)\/.*$/','$1', 'this-is-the-example/exa/mple');
Hope this helps. :)
Simply try this code:
<?php
$this_example = substr("this-is-the-example/exa", 0, -4);
echo "<br/>".$this_example; // returns "this-is-the-example"
?>
To allow for error handling, if the substring is not found in the search string ...
<?php
$myString = 'this-is-the-example/exa';
//[Edit: see comment below] use strrpos, not strpos, to find the LAST occurrence
$endPosition = strrpos($myString, '/exa');
// TodO; if endPosition === False then handle error, substring not found
$leftPart = substr($myString, 0, $endPosition);
echo($leftPart);
?>
outputs
this-is-the-example
What is the most efficient pattern to replace dots in dot-separated string to an array-like string e.g x.y.z -> x[y][z]
Here is my current code, but I guess there should be a shorter method using regexp.
function convert($input)
{
if (strpos($input, '.') === false) {
return $input;
}
$input = str_replace_first('.', '[', $input);
$input = str_replace('.', '][', $input);
return $input . ']';
}
In your particular case "an array-like string" can be easily obtained using preg_replace function:
$input = "x.d.dsaf.d2.d";
print_r(preg_replace("/\.([^.]+)/", "[$1]", $input)); // "x[d][dsaf][d2][d]"
From what I can understand from your question; "x.y.z" is a String and so should "x[y][z]" be, right?
If that is the case, you may want to give the following code snippet a try:
<?php
$dotSeparatedString = "x.y.z";
$arrayLikeString = "";
//HERE IS THE REGEX YOU ASKED FOR...
$arrayLikeString = str_replace(".", "", preg_replace("#(\.[a-z0-9]*[^.])#", "[$1]", $dotSeparatedString));
var_dump($arrayLikeString); //DUMPS: 'x[y][z]'
Hope it helps you, though....
Using a fairly simple preg_replace_callback() that simply returns a different replacement for the first occurrence of . compared to the other occurrences.
$in = "x.y.z";
function cb($matches) {
static $first = true;
if (!$first)
return '][';
$first = false;
return '[';
}
$out = preg_replace_callback('/(\.)/', 'cb', $in) . ((strpos('.', $in) !== false) ? ']' : ']');
var_dump($out);
The ternary append is to handle the case of no . to replace
already answered but you could simply explode on the period delimiter then reconstruct a string.
$in = 'x.y.z';
$array = explode('.', $in);
$out = '';
foreach ($array as $key => $part){
$out .= ($key) ? '[' . $part . ']' : $part;
}
echo $out;
This is my string:
monkey/rabbit/cat/donkey/duck
If my variable is cat...
$animal = cat
... I want to remove everything coming after cat.
My desired result is:
monkey/rabbit/cat
I tried to use str_replace:
$subject = 'monkey/rabbit/cat/donkey/duck';
$trimmed = str_replace($animal, '', $subject);
echo $trimmed;
But here I get the result:
monkey/rabbit//donkey/duck
So it is just cutting out cat.
You can combine strpos with substr:
$pos = strpos($subject, $animal);
if ($pos !== false) {
$result = substr($subject, 0, $pos + strlen($animal));
}
If you wold like to make sure it only the full segments are erased, in case of a partial match, you could use the offset argument of strpos:
$pos = strpos($subject, $animal);
if ($pos !== false) {
$result = substr($subject, 0, strpos($subject, '/', $pos));
}
You can use explode in your case:
$string = "monkey/rabbit/cat/donkey/duck";
$val = explode("donkey", $string );
echo $val[0];
Result: monkey/rabbit/cat
PS* Ofcourse there are better ways to do this
My approach would be to explode by your variable.
Take the first part and append the variable.
<?php
$string = 'monkey/rabbit/cat/donkey/duck';
$animal = 'cat';
$temp = explode($animal,$string);
print $temp[0] . $animal;
Will output nicely
monkey/rabbit/cat
There's no need to use any of strpos, strlen, substr or donkeys
<?php
$animal="cat";
$string1="monkey/rabbit/cat/donkey/duck";
$parts = explode($animal, $string1);
$res = $parts[0];
print("$res$animal")
?>
Here is a bit of explanation for what each step does:
$subject = 'monkey/rabbit/cat/donkey/duck';
$target = 'cat';
$target_length = strlen($target); // get the length of your target string
$target_index = strpos($subject, $target); // find the position of your target string
$new_length = $target_index + $target_length; // find the length of the new string
$new_subject = substr($subject, 0, $new_length); // trim to the new length using substr
echo $new_subject;
This can all be combined into one statement.
$new_subject = substr($subject, 0, strpos($subject, $target) + strlen($target));
This assumes your target is found. If the target is not found, the subject will be trimmed to the length of the target, which obviously is not what you want. For example, if your target string was "fish" the new subject would be "monk". This is why the other answer checks if ($pos !== false) {.
One of the comments on your question raises a valid point. If you search for a string that happens to be contained in one of the other strings, you may get unexpected results. There is really not a good way to avoid this problem when using the substr/strpos method. If you want to be sure to only match a complete word between your separators (/), you can explode by / and search for your target in the resulting array.
$subject = explode('/', $subject); // convert to array
$index = array_search($target, $subject); // find the target
if ($index !== false) { // if it is found,
$subject = array_slice($subject, 0, $index + 1); // remove the end of the array after it
}
$new_subject = implode('/', $subject); // convert back to string
I'm probably going to kop some flak for going down the RegExp route but...
$subject = 'monkey/rabbit/polecat/cat/catfish/duck';
$animal = "cat";
echo preg_replace('~(.*(?:/|^)' . preg_quote($animal) . ')(?:/|$).*~i', "$1", $subject);
This will ensure that your animal is wrapped immediately on either side with / characters, or that it's at the start or end of the string (i.e. monkey or duck).
So in this example it'll output:
monkey/rabbit/polecat/cat
Ending specifically with cat rather than stumbling at polecat or catfish
It might seem easy to do but I have trouble extracting this string. I have a string that has # tags in it and I'm trying to pull the tags maps/place/Residences+Jardins+de+Majorelle/#33.536759,-7.613825,17z/data=!3m1!4b1!4m2!3m1!1s0xda62d6053931323:0x2f978f4d1aabb1aa
And here is what I want to extract 33.536759,-7.613825,17z :
$var = preg_match_all("/#(\w*)/",$path,$query);
Any way I can do this? Much appreciated.
Change your regex to this one: /#([\w\d\.\,-]*)/.
This will return the string beginning with #.
$string = 'maps/place/Residences+Jardins+de+Majorelle/#33.536759,-7.613825,17z/data=!3m1!4b1!4m2!3m1!1s0xda62d6053931323:0x2f978f4d1aabb1aa';
$string = explode('/',$string);
//$coordinates = substr($string[3], 1);
//print_r($coordinates);
foreach ($string as $substring) {
if (substr( $substring, 0, 1 ) === "#") {
$coordinates = $substring;
}
}
echo $coordinates;
This is working for me:
$path = "maps/place/Residences+Jardins+de+Majorelle/#33.536759,-7.613825,17z/data=!3m1!4b1!4m2!3m1!1s0xda62d6053931323:0x2f978f4d1aabb1aa";
$var = preg_match_all("/#([^\/]+)/",$path,$query);
print $query[1][0];
A regex would do.
/#(-*\d+\.\d+),(-*\d\.\d+,\d+z*)/
If there is only one # and the string ends with / you can use the following code:
//String
$string = 'maps/place/Residences+Jardins+de+Majorelle/#33.536759,-7.613825,17z/data=!3m1!4b1!4m2!3m1!1s0xda62d6053931323:0x2f978f4d1aabb1aa';
//Save string after the first #
$coordinates = strstr($string, '#');
//Remove #
$coordinates = str_replace('#', '', $coordinates);
//Separate string on every /
$coordinates = explode('/', $coordinates );
//Save first part
$coordinates = $coordinates[0];
//Do what you want
echo $coordinates;
do like this
$re = '/#((.*?),-(.*?),)/mi';
$str = 'maps/place/Residences+Jardins+de+Majorelle/#33.536759,-7.613825,17z/data=!3m1!4b1!4m2!3m1!1s0xda62d6053931323:0x2f978f4d1aabb1aa';
preg_match_all($re, $str, $matches);
echo $matches[2][0].'<br>';
echo $matches[3][0];
output
33.536759
7.613825