php move vaiable substring to end of string - php

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];

Related

Understanding strpos, preg_replace, and preg_match functions

I'm working on a WordPress site and want to add rel="noreferrer noopener" to all external links. I have found a function that is doing exactly what I want, but I would like to expand it. What I want to do is if the link has rel="nofollow", then replace it with rel="nofollow noopener noreferrer".
Here is the function I'm working on, and I have difficulties to understand several functions. I would like to understand them so I can resolve my issue.
add_filter('the_content', 'rel_function');
function rel_function($content) {
return preg_replace_callback('/<a[^>]+/', 'rel_all_external_links', $content);
}
function rel_all_external_links($Matches) {
$externalLink = $Matches[0];
$SiteLink = get_bloginfo('url');
if (strpos($link, 'rel') === false) {
$externalLink = preg_replace("%(href=\S(?!$SiteLink))%i", 'rel="noopener noreferrer" target="_blank" $1', $externalLink);
} elseif (preg_match("%href=\S(?!$SiteLink)%i", $externalLink)) {
$externalLink = preg_replace('/rel=\S(?!nofollow)\S*/i', 'rel="noopener noreferrer" target="_blank"', $externalLink);
}
return $externalLink;
}
First thing I don't understand is if (strpos($link, 'rel') === false). How come is that $link is undefined? I don't understand how strpos is getting value for this variable? And does this returns true if the link doesn't have 'rel'?
The second is $externalLink = preg_replace("%(href=\S(?!$SiteLink))%i", 'rel="noopener noreferrer" target="_blank" $1', $externalLink);
If I'm understanding correctly, preg_replace checks if $extenalLink doesn't contain base URL and replace all string except href="..."? Is that correct?
And the last one:
elseif (preg_match("%href=\S(?!$SiteLink)%i", $externalLink)) {
$externalLink = preg_replace('/rel=\S(?!nofollow)\S*/i', 'rel="noopener noreferrer" target="_blank"', $externalLink);
}
It checks if $externalLink doesn't have a base URL, right? I'm not sure what preg_replace is trying to do here, but I think it is the key to my problem.
I would appreciate any help.
strpos is a function that allows you to find if a specific word or combination of characters present in the string you provided. It's like yes/no and additionally, it can give you it's start location. It is important to note that it will return false when nothing is found or a number, including 0 when the match is found.
So this function is very good for simple scenarios like does it have letters app in the word apple? the answer is yes, and the start position is 0.
In the example, you provided if (strpos($link, 'rel') === false) it searches if word rel is present, and it doesn't matter in what position.
preg_match is used for much complex searching using regex, capable of searching multiple conditions, groups and more. To give an example of what it can search: the word apprehensive does it starts with app and ends with sive? - answer yes. If strpos would've been used, it would say yes to all such cases due to the app being present but the ending is never checked as it's incapable of such thing. preg_match can commonly be used to get what's inside of an attribute, so it grabs rel="[what's here]".
Preg_replace is replacing something using regex for complex searching first, then do the replacement of a match.
I would always advise to read up documentation provided by php for the functions and it's accepted arguments.
Information about strpos
Information about preg_replace
Information about preg_match
Information about regex (takes a good while to learn!)

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.

Trim PHP String with variable within it

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

How do I find a url in a string closest to a substring(after using stripos)? (PHP)

I'm working with an html string and trying to find the closest url in position to the substring.
if (stripos($theemailmessage,'substring') !== FALSE )
{
$indicatornumber = '1';
}
So stripos() should give me the position of this substring inside the string. How would I go about searching for values within a url from here? I'm assuming it would be something traversing the string positions looking for http:// , but I'm really not sure which function I should be using.
There are many URLs in the document that I am searching for, I'm searching for the one closest to the string position. Actually, I want to search to see if the string is inside an anchor tag first, but I figured I'd start by learning how to search for the closest url, and then refine from there.
Something like this?
preg_match('/http\:\/\/[a-zA-Z0-9-.]+.[a-zA-Z]{2,3}(\/\S*)?/',$str, $url);
echo $url[0];
you have several options to implement this. use preg_replace function or use parse_url function.
$tempText = "hello.. how are you?? are you keeping well?? please checkout this url http://www.youtube.com/watch?v=ehuwoGVLyhg&feature=topvideos";
print_r(parse_url($tempText,PHP_URL_PATH));
Good luck finding a regexp to match URLs, but suppose you have one.
Then,
preg_match_all($url_regexp, $source, $matches, PREG_OFFSET_CAPTURE);
Take a look in $matches and you will have every URL plus its position. Iterate over these to find which is closest to your substring position. Make sure that you account for the length of the matches and your substring.

Replacing Tags with Includes in PHP with RegExps

I need to read a string, detect a {VAR}, and then do a file_get_contents('VAR.php') in place of {VAR}. The "VAR" can be named anything, like TEST, or CONTACT-FORM, etc. I don't want to know what VAR is -- not to do a hard-coded condition, but to just see an uppercase alphanumeric tag surrounded by curly braces and just do a file_get_contents() to load it.
I know I need to use preg_match and preg_replace, but I'm stumbling through the RegExps on this.
How is this useful? It's useful in hooking WordPress.
Orion above has a right solution, but it's not really necessary to use a callback function in your simple case.
Assuming that the filenames are A-Z + hyphens you can do it in 1 line using PHP's /e flag in the regex:
$str = preg_replace('/{([-A-Z]+)}/e', 'file_get_contents(\'$1.html\')', $str);
This'll replace any instance of {VAR} with the contents of VAR.html. You could prefix a path into the second term if you need to specify a particular directory.
There are the same vague security worries as outlined above, but I can't think of anything specific.
You'll need to do a number of things. I'm assuming you can do the legwork to get the page data you want to preprocess into a string.
First, you'll need the regular expression to match correctly. That should be fairly easy with something like /{\w+}/.
Next you'll need to use all of the flags to preg_match to get the offset location in the page data. This offset will let you divide the string into the before, matching, and after parts of the match.
Once you have the 3 parts, you'll need to run your include, and stick them back together.
Lather, rinse, repeat.
Stop when you find no more variables.
This isn't terribly efficient, and there are probably better ways. You may wish to consider doing a preg_split instead, splitting on /[{}]/. No matter how you slice it you're assuming that you can trust your incoming data, and this will simplify the whole process a lot. To do this, I'd lay out the code like so:
Take your content and split it like so: $parts = preg_split('/[{}]/', $page_string);
Write a recursive function over the parts with the following criteria:
Halt when length of arg is < 3
Else, return a new array composed of
$arg[0] . load_data($arg[1]) . $arg[2]
plus whatever is left in $argv[3...]
Run your function over $parts.
You can do it without regexes (god forbid), something like:
//return true if $str ends with $sub
function endsWith($str,$sub) {
return ( substr( $str, strlen( $str ) - strlen( $sub ) ) === $sub );
}
$theStringWithVars = "blah.php cool.php awesome.php";
$sub = '.php';
$splitStr = split(" ", $theStringWithVars);
for($i=0;$i<count($splitStr);$i++) {
if(endsWith(trim($splitStr[$i]),$sub)) {
//file_get_contents($splitStr[$i]) etc...
}
}
Off the top of my head, you want this:
// load the "template" file
$input = file_get_contents($template_file_name);
// define a callback. Each time the regex matches something, it will call this function.
// whatever this function returns will be inserted as the replacement
function replaceCallback($matches){
// match zero will be the entire match - eg {FOO}.
// match 1 will be just the bits inside the curly braces because of the grouping parens in the regex - eg FOO
// convert it to lowercase and append ".html", so you're loading foo.html
// then return the contents of that file.
// BEWARE. GIANT MASSIVE SECURITY HOLES ABOUND. DO NOT DO THIS
return file_get_contents( strtolower($matches[1]) . ".html" );
};
// run the actual replace method giving it our pattern, the callback, and the input file contents
$output = preg_replace_callback("\{([-A-Z]+)\}", replaceCallback, $input);
// todo: print the output
Now I'll explain the regex
\{([-A-Z]+)\}
The \{ and \} just tell it to match the curly braces. You need the slashes, as { and } are special characters, so they need escaping.
The ( and ) create a grouping. Basically this lets you extract particular parts of the match. I use it in the function above to just match the things inside the braces, without matching the braces themselves. If I didn't do this, then I'd need to strip the { and } out of the match, which would be annoying
The [-A-Z] says "match any uppercase character, or a -
The + after the [-A-Z] means we need to have at least 1 character, but we can have up to any number.
Comparatively speaking, regular expression are expensive. While you may need them to figure out which files to load, you certainly don't need them for doing the replace, and probably shouldn't use regular expressions. After all, you know exactly what you are replacing so why do you need fuzzy search?
Use an associative array and str_replace to do your replacements. str_replace supports arrays for doing multiple substitutions at once. One line substitution, no loops.
For example:
$substitutions = array('{VAR}'=>file_get_contents('VAR.php'),
'{TEST}'=>file_get_contents('TEST.php'),
...
);
$outputContents = str_replace( array_keys($substitutions), $substitutions, $outputContents);

Categories