Trim PHP String with variable within it - php

I seek your assistance once more with a small problem I am having, the solution is potentially obvious/looking at me in the face, but I have yet to resolve my issue.
I have the need to trim a string which happens to have a variable within it. (the string is actually a URL)
An example String/URL:
/portal/index.php?module=SerialDB&page=listing&returnmsg=3
&returnmsg=3 can be a range of numbers from 0 to 100, as well as, in some cases, text. This is the variable I need to trim as I am hoping to store the rest of the string/URL into a database. The following is the result I seek;
/portal/index.php?module=SerialDB&page=listing
I have tried the following code just to see if it could appropriate the function I require, but unfortunately it is more specific and won't trim unless it gets an EXACT match.
$str = "/portal/index.php?module=SerialDB&returnmsg=3";
echo $str . "<br>"; // Test to see full string
echo chop($str,"&returnmsg="); // Attempt to trim the string
If anyone is up to the task of assisting I would be greatly appreciative. As with all my questions, I would also like to understand what is happening as opposed to just being handed the code so I can use it confidently in the future.
Thanks once again guys :)

A quick way that doesn't depend on parameter order is just to take apart the pieces, pick out what you want, and then put them back together again (you can look up the various PHP functions for more details):
$urlParts = parse_url($url);
parse_str($urlParts['query'], $queryParts);
$returnMsg = $queryParts['returnmsg'];
unset($queryParts['returnmsg']);
$urlParts['query'] = http_build_query($queryParts);
$url = http_build_url($urlParts);

Simple. The concept is known as slicing.
$url = "/portal/index.php?module=SerialDB&page=listing&returnmsg=3";
$new_url = substr( $url, 0, strrpos( $url, '&') );
result is: /portal/index.php?module=SerialDB&page=listing
The substr() function returns part of a string. It takes three parameters. Parameter #1 is the string you are going to extract from, parameter #2 is where are you going to start from and parameter #3 is the length of the slice or how many characters you want to extract.
The strrpos() function returns the position/index of the last occurrence of a substring in a string. Example: if you have the string "zazz" the position of the last z will be returned. You can think of it as "string reverse position". This function accepts three parameters. I will only cover two as this is the number I used in this example. Parameter #1 is the string you are searching in, parameter #2 is the needle or what you are looking for, in your case the &. As I mentioned in the beginning of this paragraph, it returns the position in the form of an integer. In your case that number was 46.
So the strrpos() as the third parameter in substr() is telling it up to where to slice the string. Upon completion it returns the segment that you wanted to extract.
It would be helpful if you read the PHP Manual and looked over the available functions that might help you in the future. You can combine these functions in various ways to solve your problems.
http://php.net/manual/en/funcref.php

If returnmsg is always the last param (and not the first) in your url and if your url doesn't contain an anchor, so in short the param is always at the end, you can solve the problem with a simple explode:
$url = explode('&returnmsg=', $url)[0];
(you split the string with &returnmsg= and you keep the first part).
otherwise as suggested in comments you can use a regex replacement:
$url = preg_replace('~[?&]returnmsg=[^&#]*~', '', $url);
pattern details:
~ # pattern delimiter
[?&] # a literal "?" or a literal "&"
returnmsg=
[^&#]* # any characters except "&" or "#" zero or more times
~
(for the two ways, if the param is not present, the url stay unchanged.)

I don't weather it comes in starting or in end so if it comes in end then use the code below.
<?php
$url="/portal/index.php?module=SerialDB&page=listing&returnmsg=3";
$array= explode("&",$url);
$new_url="";
foreach($array as $p){
if(strpos($p,"returnmsg")===false){
$new_url .=$p."&";
}
}
echo rtrim($new_url, "&");
The above code is exploding the array & and then running a foreach loop to join them.
#Bobdye answer is also correct but there is a bit problem in that code, that wasn't running for me. Use the code below
<?php
$url="/portal/index.php?module=SerialDB&page=listing&returnmsg=3";
$urlParts = parse_url($url);
parse_str($urlParts['query'], $queryParts);
$returnMsg = $queryParts['returnmsg'];
unset($queryParts['returnmsg']);
$urlParts['query'] = http_build_query($queryParts);
$url = http_build_query($urlParts);
var_dump($url);
Hope this helps you

Related

Extract only numbers from link with codeception

I have this link, and i need to work only with the numbers from that link.
How would i extract them?
I didn't find any answer that would work with codepcetion.
https://www.my-website.com/de/booking/extras#tab-nav-extras-1426
I tired something like this.
$I->grabFromCurrentUrl('\d+');
But i won't work.
Any ideas ?
Staying within the framework:
The manual clearly says that:
grabFromCurrentUrl
Executes the given regular expression against the current URI and
returns the first capturing group. If no parameters are provided, the
full URI is returned.
Since you didn't used any capturing groups (...), nothing is returned.
Try this:
$I->grabFromCurrentUrl('~(\d+)$~');
The $ at the end is optional, it just states that the string should end with the pattern.
Also note that the opening and closing pattern delimiters you would normally use (/) are replaced by tilde (~) characters for convenience, since the input string has a great chance to contain multiple forward slashes. Custom pattern delimiters are completely standard in regexp, as #Naktibalda pointed it out in this answer.
You can use parse_url() to parse entire URL and then extract the part which is most interested for you. After that you can use regex to extract only numbers from the string.
$url = "https://www.my-website.com/de/booking/extras#tab-nav-extras-1426";
$parsedUrl = parse_url($url);
$fragment = $parsedUrl['fragment']; // Contains: tab-nav-extras-1426
$id = preg_replace('/[^0-9]/', '', $fragment);
var_dump($id); // Output: string(4) "1426"
A variant using preg_match() after parse_url():
$url = "https://www.my-website.com/de/booking/extras#tab-nav-extras-1426";
preg_match('/\d+$/', parse_url($url)['fragment'], $id);
var_dump($id[0]);
// Outputs: string(4) "1426"

php move vaiable substring to end of string

say I have a string:
something.something/search?&abc=xyz:??????q=hello+there
or
something.something/search?abc=xyz:??????q=hello+there
I need to move variable substring: [&]abc=xyz:?????? to the end of sting.
So I wind up with:
something.something/search?q=hello+there&abc=xyz:??????
The substring is unknown at the start in terms of how long it is.
We know the substring starts right after the first ? and that it
starts with &abc=xyz:????? possibly or abc=xyx:????? possibly.
There may or may not be the ????? and they are of indeterminate length.
and content.
We know the the substring ends at the q=.......
So what is between first ? to first q= gets removed and added to string.
However that ending must begin with an & and only 1 &.
All this only applies for strings containing something.something/search?.
The substring is quite a variable.
I am also wondering if I should test for something before I try the change.
Thanks
It says to edit question so here goes. I think you are getting close.
A typical $url would be:
https://www._oogle.com/search?&tbs=qdr:q=hello+there //hello+there only example.
https://www._oogle.com/search?tbs=qdr:q=hello+there //...qdr:null|h|d|w|m|y which is for past page searches. (how old) null(all),hour,day,week,month,year.
If the tbs:qdr part comes first other things break, so I have to move it after
the q=... part.
And of course the are the http:// varients to be considered.
I was thinking to use a contains function I made to see if this $url needs this treatment. It needs to catch the "_oogle.com/search?&tbs=qdr:" possibility however. (starts with ampersand) [null|&]tbs=qdr:[null|h|d|w|m|y] . I guess there could possibly be other parameters before the "q=" part, but lets worry about that later.
if (contains($url, "_oogle.com/search?tbs=qdr:"))
function contains($haystack, $needle) {
if(stristr($haystack, $needle) === FALSE) { return false; }
else {return $needle; }
I don't know if this is exactly what you are looking for, but your can try to use a regex on your params. If you have more params before and after the q= you will have to manipulate the regex a little more and you will have to loop in an array to define the correct position of the param you are looking for. Here is an example of what you could do.
$baseUrl = 'http://www.google.com';
$parseUrl = parse_url($baseUrl.'/search?&abc=xyz:??????q=hello+there');
preg_match_all('/&?(.*)q=(.*)/',$parseUrl['query'],$matches, PREG_PATTERN_ORDER);
echo $baseUrl.'/search?q='.$matches[2][0].'&'.$matches[1][0];

Replace many code lines in PHP between tags

I have gotten a page php with this line:
$url = file_get_contents('http://web.com/rss.php');
Now I want replace this:
<link>http://web.com/download/45212/lorem-ipsum</link>
<link>http://web.com/download/34210/dolor-sit</link>
<link>http://web.com/download/78954/consectetur-adipiscing</link>
<link>http://web.com/download/77741/laboris-nisi</link>...
With this:
<link>http://otherweb.com/get-d/45212</link>
<link>http://otherweb.com/get-d/34210</link>
<link>http://otherweb.com/get-d/78954</link>
<link>http://otherweb.com/get-d/77741</link>...
I have replaced a part with str_replace but I don't know to replace the other part.
This is what i have done for the moment:
$url = str_replace('<link>http://web.com/download/','<link>http://otherweb.com/get-d/', $url);
You can do this all with a single line of regex :)
Regex
The below regex will detect your middle numbered section....
<link>http:\/\/web\.com\/download\/(.*?)\/.*?<\/link>
PHP
To use this inside PHP you could use this line of code
$url = preg_replace("/<link>http:\/\/web\.com\/download\/(.*?)\/.*?<\/link>/m", "<link>http://otherweb.com/get-d/$1</link>", $url);
This should do exactly what you need!
Explanation
The way it works is preg_replace looks for <link>http://web.com/download/ at the start and /{something}</link> at the end. It captures the middle area into $1
So when we run preg_replace ($pattern, $replacement, $subject) we tell PHP to just find that middle part (the numbers in your URLS) and embed them into "<link>http://otherweb.com/get-d/$1</link>".
I tested it and it seems to be working :)
Edit: I would propose this answer as best for you as it does everything with a single line, and does not require any str_replace. My answer also will function even if the middle section is alphanumeric, and not only if it is numeric.
All you want to do is:
extract the relevant data e.g. the five digit number
put the extracted part into a new context
$input = 'http://web.com/download/45212/lorem-ipsum';
echo preg_replace('/.*\/(\d+).*/', 'http://otherweb.com/get-d/$1', $input);
To extract the relevant part, you can use (\d+) which means: find one or more digits, the parentheses make this a matching group, so you can access this value via $1.
To match and replace the whole line, you have to augment the pattern with .* (which means, find any number of any character) before and after the (\d+) part.
With this set up, the whole string matches, so the whole string will be replaced.
You should replace the initial part of link with a token, and then preg_replace the end of your string searching for the first / and replacing with the </link>. And so you replace your token with the initial part you desire.
$url = str_replace('<link>http://web.com/download/','init', $url);
$url = preg_replace("/\/.+/", "</link>", $url);
$url = str_replace('init', '<link>http://otherweb.com/get-d/', $url);
You're just missing a simple regex to clean up the last part.
Here's how I did it:
$messed_up = '
<link>http://web.com/download/45212/lorem-ipsum</link>
<link>http://web.com/download/34210/dolor-sit</link>
<link>http://web.com/download/78954/consectetur-adipiscing</link>
<link>http://web.com/download/77741/laboris-nisi</link>';
// Firstly we can clean up the first part (like you did) with str_replace
$clean = str_replace('web.com/download/','otherweb.com/get-d/', $messed_up);
// After that we'll use preg_replace to get rid of the last part
$clean = preg_replace("/(.+\/\d+)\/.*(<.*)/", "$1$2", $clean);
printf($clean);
/* Returns:
<link>http://otherweb.com/get-d/4521</link>
<link>http://otherweb.com/get-d/3421</link>
<link>http://otherweb.com/get-d/7895</link>
<link>http://otherweb.com/get-d/7774</link>
*/
I made this quickly so there might be some room for improvement but it definitely works.
You can check out the code in practice HERE.
If you're interested in learning PHP RegEx This is a great place to practice.

How to get a number from a html source page?

I'm trying to retrieve the followed by count on my instagram page. I can't seem to get the Regex right and would very much appreciate some help.
Here's what I'm looking for:
y":{"count":
That's the beginning of the string, and I want the 4 numbers after that.
$string = preg_replace("{y"\"count":([0-9]+)\}","",$code);
Someone suggested this ^ but I can't get the formatting right...
You haven't posted your strings so it is a guess to what the regex should be... so I'll answer on why your codes fail.
preg_replace('"followed_by":{"count":\d')
This is very far from the correct preg_replace usage. You need to give it the replacement string and the string to search on. See http://php.net/manual/en/function.preg-replace.php
Your second usage:
$string = preg_replace(/^y":{"count[0-9]/","",$code);
Is closer but preg_replace is global so this is searching your whole file (or it would if not for the anchor) and will replace the found value with nothing. What your really want (I think) is to use preg_match.
$string = preg_match('/y":\{"count(\d{4})/"', $code, $match);
$counted = $match[1];
This presumes your regex was kind of correct already.
Per your update:
Demo: https://regex101.com/r/aR2iU2/1
$code = 'y":{"count:1234';
$string = preg_match('/y":\{"count:(\d{4})/', $code, $match);
$counted = $match[1];
echo $counted;
PHP Demo: https://eval.in/489436
I removed the ^ which requires the regex starts at the start of your string, escaped the { and made the\d be 4 characters long. The () is a capture group and stores whatever is found inside of it, in this case the 4 numbers.
Also if this isn't just for learning you should be prepared for this to stop working at some point as the service provider may change the format. The API is a safer route to go.
This regexp should capture value you're looking for in the first group:
\{"count":([0-9]+)\}
Use it with preg_match_all function to easily capture what you want into array (you're using preg_replace which isn't for retrieving data but for... well replacing it).
Your regexp isn't working because you didn't escaped curly brackets. And also you didn't put count quantifier (plus sign in my example) so it would only capture first digit anyway.

Get last parameter from the URL

I want to get the last parameter from the following type of structure:
$current_url = "/wp/author/admin/1";
So, from above url I will like to get "1"
The following code will return it correctly, but here I'm specifying the exact position of the variable. How can I get the last parameter without specifying its position (eg. no matter how many parameters are in the URL, just get the last one):
$parts = explode('/', $current_url);
var_dump($parts[4]);
I would suggest using a regular expression for this, as you can do quite a few nice things, e.g. also allow URLs that end in /:
if (!preg_match('/\/([^\/]*)\/?$/', $current_url, $matches)
// do something if the URL does not match the pattern
$lastComponent = $matches[1];
What's happening here? The regular expression matches if it can find a forward slash (the \/) followed by any number of characters that are not slashes (the ([^\/]*)), which may then optionally be followed by another slash (the \/?), and then arrives at the end of the string (the $).
The function returns a value that evaluates to false if the regular expression did not match, so you are prepared for garbage input and may emit a warning if appropriate. Notice the parentheses in ([^\/]*), which will take all the characters mathced here (everything from the slash to the end of the input string or the last slash), and put it into its own match ($matches[1]).
I recommend you try regexpal.com if you want to debug and check your regular expressions. They are very powerful tools and quite underused in programming. Especially in PHP, where you get nice functions for them (e.g. preg_match, preg_match_all, and preg_match_split).
after you explode the array use the end() function. That will always grab the last element in the array.
http://us1.php.net//manual/en/function.end.php
I'm sure there are other methods, I would use array_pop
$parts = explode('/', $current_url);
var_dump(array_pop($parts));
http://php.net/manual/en/function.array-pop.php
"array_pop() pops and returns the last value of the array, shortening the array by one element."
but the last note is important as it affects the contents of $parts array
$parts = explode("/", $url);
echo end($parts);

Categories