How to extract only parameter value from URL using ONLY Regular Expressions - php

Extract the value of the u2 parameter from this URL using a regular expression. http://www.example.com?u1=US&u2=HA853&u3=HPA
<?php
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA"; //my url
$pattern='/u2=[0-9A-Za-z]*/'; //R.E that url value is only digit/Alphabet
preg_match($pattern,$subject,$match);
print_r($match[0]);
?>
Output:-
u2=HA853
How can i retrieve only HA853?

The 0 group is everything that the regex matched so either use \K to ignore the previous matches of the regex,
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA"; //my url
$pattern='/u2=\K[0-9A-Za-z]*/'; //R.E that url value is only digit/Alphabet
preg_match($pattern,$subject,$match);
print_r($match[0]);
or use a second capture group:
...
$pattern='/u2=([0-9A-Za-z]*)/'; //R.E that url value is only digit/Alphabet
...
print_r($match[1]);
Why you'd need to do that though is unclear to me, http://php.net/manual/en/function.parse-str.php, seems like a simpler approach.
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA";
parse_str($subject, $output);
echo $output['u2'];
Demo: https://3v4l.org/gR4cb

Other way is to use parse_url,http://php.net/manual/en/function.parse-url.php
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA";
$query_string = parse_url($subject, PHP_URL_QUERY); // get query string
$parameters = explode('&', $query_string); //Explode with &
$array = array(); // define an empty array
foreach($parameters as $val)
{
$param= explode('=', $val);
$array[$param[0]] = $param[1];
}
echo $array['u2']; // outputs HA853
print_r($array);
Array
(
[u1] => US
[u2] => HA853
[u3] => HPA
)

Related

Replacing values in string

I have a string which contains certain number of #{number} structures. For example:
#328_#918_#1358
SKU:#666:#456
TEST--#888/#982
For each #{number} structure, I have to replace it with a known string.
For the first example:
#328_#918_#1358
I have the following strings:
328="foo"
918="bar"
1358"arg"
And the result should be:
foo_bar_arg
How do I achieve such effect? My current code looks like that:
$matches = array();
$replacements = array();
// starting string
$string = "#328_#918:#1358";
// getting all the numbers from the string
preg_match_all("/\#[0-9]+/", $string, $matches);
// getting rid of #
foreach ($matches[0] as $key => &$feature) {
$feature = preg_replace("/#/", "", $feature);
} // end foreach
// obtaining the replacement values
foreach ($matches[0] as $key => $value) {
$replacement[$value] = "fizz"; // here the value required for replacement is obtained
} // end foreach
But I have no idea how to actually perform a replacement in $string variable using values from $replacement table. Any help is much appreciated!
You can use a preg_replace_callback solution:
$string = '#328_#918:#1358
SKU:#666:#456
TEST--#888/#982';
$replacements = [328=>"foo", 918=>"bar", 1358=>"arg"];
echo preg_replace_callback("/#([0-9]+)/", function ($m) use ($replacements) {
return isset($replacements[$m[1]]) ? $replacements[$m[1]] : $m[0];
}
,$string);
See the PHP demo.
The #([0-9]+) regex will match all non-overlapping occurrences of # and one or more digits right after capturing them into Group 1. If there is an item in the replacements associative array with the numeric key, the whole match is replaced with the corresponding value. Else, the match is returned so that no replacement could occur and the match does not get removed.

Check if URL contains string then create variables with url strings

I need to check if URL contains the term: "cidades".
For example:
http://localhost/site/cidades/sp/sorocaba
So, if positive, then I need to create two or three variables with the remaining content without the " / ", in this case:
$var1 = "sp";
$var2 = "sorocaba";
These variables will be cookies values in the beggining of the page, then, some sections will use as wp-query these values to filter.
This should work for you:
Here I check with preg_match() if the search word is in the url $str between two slashes. If yes I get the substr() from the url after the search word and explode() it into an array with a slash as delimiter. Then you can simply loop through the array an create the variables with complex (curly) syntax.
<?php
$str = "http://localhost/site/cidades/sp/sorocaba";
$search = "cidades";
if(preg_match("~/$search/~", $str, $m, PREG_OFFSET_CAPTURE)) {
$arr = explode("/", substr($str, $m[0][1]+strlen($m[0][0])));
foreach($arr as $k => $v)
${"var" . ($k+1)} = $v;
}
echo $var1 . "<br>";
echo $var2;
?>
output:
sp
sorocaba
Here are two functions that will do it for you:
function afterLast($haystack, $needle) {
return substr($haystack, strrpos($haystack, $needle)+strlen($needle));
}
And PHP's native explode.
First call afterLast, passing the /cidades/ string (or just cidades if you don't expect the slashes). Then take the result and explode on / to get your resulting array.
It would look like:
$remaining_string = afterLast('/cidades/', $url);
$items = explode('/', $remaining_string)
Just note that if you do not include the / marks with the afterLast call, your first element in the explode array will be empty.
I think this solution is better, since the resulting array will support any number of values, not just two.

Error parsing regex pattern in php

I want to split a string such as the following (by a divider like '~##' (and only that)):
to=enquiry#test.com~##subject=test~##text=this is body/text~##date=date
into an array containing e.g.:
to => enquiry#test.com
subject => test
text => this is body/text
date => date
I'm using php5 and I've got the following regex, which almost works, but there are a couple of errors and there must be a way to do it in one go:
//Split the string in the url of $text at every ~##
$regexp = "/(?:|(?<=~##))(.*?=.*?)(?:~##|$|\/(?!.*~##))/";
preg_match_all($regexp, $text, $a);
//$a[1] is an array containing var1=content1 var2=content2 etc;
//Now create an array in the form [var1] = content, [var2] = content2
foreach($a[1] as $key => $value) {
//Get the two groups either side of the equals sign
$regexp = "/([^\/~##,= ]+)=([^~##,= ]+)/";
preg_match_all($regexp, $value, $r);
//Assign to array key = value
$val[$r[1][0]] = $r[2][0]; //e.g. $val['subject'] = 'hi'
}
print_r($val);
My queries are that:
It doesn't seem to capture more than 3 different sets of parameters
It is breaking on the # symbol and so not capturing email addresses e.g. returning:
to => enquiry
subject => test
text => this is body/text
I am doing multiple different regex searches where I suspect I would be able to do one.
Any help would be really appreciated.
Thanks
Why are you using regex when there is much simple method to do this by explode like this
$str = 'to=enquiry#test.com~##subject=test~##text=this is body/text~##date=date';
$array = explode('~##',$str);
$finalArr = array();
foreach($array as $val)
{
$tmp = explode('=',$val);
$finalArr[$tmp['0']] = $tmp['1'];
}
echo '<pre>';
print_r($finalArr);

Grab a word in a complex url by php

Hi I have this url where i want to grab the last word (oath2_access_token) after the equals sign by PHP where the last word can be anything not just oath2_acc..
https://api.linkedin.com/v1/peoplesearch:(facets:(code,buckets:(code,name,count)))?facets=industry,network&facet=industry,12&facet=network,F&oauth2_access_token=oath2_access_token
Please help to grab the word or atleast provide me the resources where i could learn and do it myself.
Thanks.
You can use explode to get all the values after the equal signs and then just get the last element of the array:
<?php
$url = 'https://api.linkedin.com/v1/peoplesearch:(facets:(code,buckets:(code,name,count)))?facets=industry,network&facet=industry,12&facet=network,F&oauth2_access_token=oath2_access_token';
$array = explode('=', $url);
$value = end(array_values($array));
echo $value;
?>
GET
(As others have pointed out) I'm not sure why you can't simply use this...
$token = $_GET['oauth2_access_token'];
http://php.net/_get
Regex
Seeing as you have tagged this question with regex...
preg_match('/.*=(.*)/', $url, $matches);
$token = $matches[1];
.*= => Select everything up to and including the last = sign (because * is greedy)
(.*) => Select everything after the last = sign and capture it
http://php.net/preg_match
http://www.regular-expressions.info/
Explode
You could also split the url on the = sign and take the last index...
$url_array = explode('=', $url);
$token = end($url_array);
http://php.net/explode
http://php.net/end
preg_match("/oauth2_access_token\=([a-z0-9_\-]+)/i", $url, $matches);
I guess this pattern should cover the token, if not you'll need to define the allowed characters between the [] brackets.
Dump $matches to see which index grabs the token.
Either use
$_GET['oauth2_access_token']
or use parse_url. :
<?php
$url = "https://api.linkedin.com/v1/peoplesearch:(facets:(code,buckets:(code,name,count)))?facets=industry,network&facet=industry,12&facet=network,F&oauth2_access_token=oath2_access_token";
$querystring_params = array();
parse_str(parse_url($url, PHP_URL_QUERY), $querystring_params);
echo $querystring_params["oauth2_access_token"];
?>

A bit lost with preg_match regular expression

I'm a beginner in regular expression so it didn't take long for me to get totally lost :]
What I need to do:
I've got a string of values 'a:b,a2:b2,a3:b3,a4:b4' where I need to search for a specific pair of values (ie: a2:b2) by the second value of the pair given (b2) and get the first value of the pair as an output (a2).
All characters are allowed (except ',' which seperates each pair of values) and any of the second values (b,b2,b3,b4) is unique (cant be present more than once in the string)
Let me show a better example as the previous may not be clear:
This is a string: 2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,never:0
Searched pattern is: 5
I thought, the best way was to use function called preg_match with subpattern feature.
So I tried the following:
$str = '2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,20 minutes:20,30 minutes:30, never:0';
$re = '/(?P<name>\w+):5$/';
preg_match($re, $str, $matches);
echo $matches['name'];
Wanted output was '5 minutes' but it didn't work.
I would also like to stick with Perl-Compatible reg. expressions as the code above is included in a PHP script.
Can anyone help me out? I'm getting a little bit desperate now, as Ive spent on this most of the day by now ...
Thanks to all of you guys.
$str = '2 minutes:2,51 seconds:51,5 minutes:5,10 minutes:10,15 minutes:51,never:0';
$search = 5;
preg_match("~([^,\:]+?)\:".preg_quote($search)."(?:,|$)~", $str, $m);
echo '<pre>'; print_r($m); echo '</pre>';
Output:
Array
(
[0] => 5 minutes:5
[1] => 5 minutes
)
$re = '/(?:^|,)(?P<name>[^:]*):5(?:,|$)/';
Besides the problem of your expression having to match $ after 5, which would only work if 5 were the last element, you also want to make sure that after 5 either nothing comes or another pair comes; that before the first element of the pair comes either another element or the beginning of the string, and you want to match more than \w in the first element of the pair.
A preg_match call will be shorter for certain, but I think I wouldn't bother with regular expressions, and instead just use string and array manipulations.
$pairstring = '2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,20 minutes:20,30 minutes:30, never:0';
function match_pair($searchval, $pairstring) {
$pairs = explode(",", $str);
foreach ($pairs as $pair) {
$each = explode(":", $pair);
if ($each[1] == $searchval) {
echo $each[0];
}
}
}
// Call as:
match_pair(5, $pairstring);
Almost the same as #Michael's. It doesn't search for an element but constructs an array of the string. You say that values are unique so they are used as keys in my array:
$str = '2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,20 minutes:20,30 minutes:30, never:0';
$a = array();
foreach(explode(',', $str) as $elem){
list($key, $val) = explode(':', $elem);
$a[$val] = $key;
}
Then accessing an element is very simple:
echo $a[5];

Categories