I have a string which looks something like this:
$fetched = name=myName zip=420424 country=myCountry;
// and so on, it is not an array
I fetch these values from an api.
I want only the zip=873289 (infact only the numbers).
So I use:
// $fetched above is the output of the function below
$fetched = file_get_contents("http://example.com");
This way I fetch the contents and can match it with this code
$zip = preg_match ('/zip=[0-9]+/', $fetched );
But I want to store it in the variable, what is function to store the matched results?
You need to indicate the part you want to capture with parentheses, then supply an extra parameter to preg_match to pick these up:
$matches=array();
if (preg_match ('/zip=([0-9]+)/', $fetched, $matches ))
{
$zip=$matches[1];
}
preg_match() stores its result in the third argument, which is passed by reference. So instead of:
$zip = preg_match ('/zip=[0-9]+/', $fetched);
You should have:
preg_match ('/zip=[0-9]+/', $fetched, $zip);
Related
I've already seen some posts about it, but my text is a bit complicated,
And I can not get it to work.
Part of my page:
otherurl":"http:\/\/cdn1-test.peer5.net:80\/edge\/71-1.stream\/playlist.m3u8?uid=35577\u0026sil=3\u0026sip=WyIxODUuMTgueC54IiwiMjEwLj4LngiLCI54LngLjE1OC5giXQ%3D%3D\u0026sid=151078248\u0026misc=4OFxyLUs7UrIeWujPzuU%3D"}}
What I tried:
preg_match("/otherurl":"http:\/\/cdn1-test.peer5.net:80\/edge\/71-1.stream\/playlist.m3u8?uid=(.*)/", $data[$n], $output);
echo $output[1];
What I want to present:
Just the number after uid=*
If the string you receive is reliably formatted like your posted examples, where the uid= parameter is the first query parameter after ? and is strictly a numeric string, you can use preg_match() to extract it by matching with (\d+) (match digits) because whatever follows in the next query parameter won't begin with a digit.
$str = 'otherurl":"http:\/\/cdn1-test.peer5.net:80\/edge\/71-1.stream\/playlist.m3u8?uid=35577\u0026sil=3\u0026sip=WyIxODUuMTgueC54IiwiMjEwLj4LngiLCI54LngLjE1OC5giXQ%3D%3D\u0026sid=151078248\u0026misc=4OFxyLUs7UrIeWujPzuU%3D"}}';
preg_match('/\?uid=(\d+)/', $str, $output);
echo $output[1];
// Prints "35577"
In practice I would avoid this though. The best way to handle this is to treat it as the JSON stream it is, in combination with PHP's built-in URL handling methods parse_url() and parse_str().
That solution looks like:
// Note: I made this segment a valid JSON string...
$input_json = '{"otherurl":"http:\/\/cdn1-test.peer5.net:80\/edge\/71-1.stream\/playlist.m3u8?uid=35577\u0026sil=3\u0026sip=WyIxODUuMTgueC54IiwiMjEwLj4LngiLCI54LngLjE1OC5giXQ%3D%3D\u0026sid=151078248\u0026misc=4OFxyLUs7UrIeWujPzuU%3D"}';
$decoded = json_decode($input_json, TRUE);
// Parse the URL and extract its query string
// PHP_URL_QUERY instructs it to get only the query string
// but if you ever need other segments that can be removed
$query = parse_url($decoded['otherurl'], PHP_URL_QUERY);
// Parse out the query string into array $parsed_params
$params = parse_str($query, $parsed_params);
// Get your uid.
echo $parsed_params['uid'];
// Prints 35577
I have a text string that is set in a variable to a value like these:
$str = 'type=showall'
or
$str = 'type=showall&skip=20'
$str = 'type=showall&skip=40'
$str = 'type=showall&skip=60'
and so on.
I need to check to see if there is a "skip" value present in the string, and if so replace it with a new number that is stored in a $newSkip variable and keep the string the same except for the change to the skip value.
For example if the string was:
$str = 'type=showall&skip=20'
and
$newSkip = 40
then I would like this to be returned:
$str = 'type=showall&skip=40'
If there was no skip value:
$str = 'type=showall'
and
$newSkip = 20
then I would like this to be returned:
$str = 'type=showall&skip=20'
I'm fairly new to PHP so still finding my way with the various functions and not sure which one/s are the best ones to use in this scenario when the text/value you're looking for may/may not be in the string.
PHP has a handy function called parse_str() which accepts a string similar to the one you have, and returns an array with key/value pairs. You'll then be able to inspect specific values and make the changes you need.
$str = 'type=showall&skip=20';
// this will parse the string and place the key/value pairs into $arr
parse_str($str,$arr);
// check if specific key exists
if (isset($arr['skip'])){
//if you need to know if it was there you can do stuff here
}
//set the newSkip value regardless
$arr['skip'] = $newSkip;
echo http_build_query($arr);
The http_build_query function will return the array into the same URI format that you started with. This function also encodes the final string so if you want to see the decoded version, you'll have to send it through urldecode().
References -
parse_str()
http_build_query()
I'm trying to figure out how I can compare values from an array against a particular string.
Basically my values look like chrisx001, chrisx002, chrisx003, chrisx004, bob001
I was looking at fnmatch() but I'm not sure this is the right choice, as what I want to do is keep chrisx--- but ignore bob--- so I need to wildcard the last bit, is there a means of doing this where I can be like
if($value == "chrisx%"){/*do something*/}
and if thats possible is it possible to double check the % value as int or similar in other cases?
Regex can tell you if a string starts with chrisx:
if (preg_match('/^chrisx/', $subject)) {
// Starts with chrisx
}
You can also capture the bit after chrisx:
preg_match('/^chrisx(.*)/', $subject, $matches);
echo $matches[1];
You could filter your array to return a second array of only those entries beginning whith 'chris' and then process that filtered array:
$testData = array ( 'chrisx001', 'chrisx002', 'chrisx003', 'chrisx004', 'bob001');
$testNeedle = 'chris';
$filtered = array_filter( $testData,
function($arrayEntry) use ($testNeedle) {
return (strpos($arrayEntry,$testNeedle) === 0);
}
);
var_dump($filtered);
if I have this url: node/95/pdf/1. How will I able to get the numeric/value 1? Tried the parse_url but gave me the wrong output.
PS: the value 1 is just an example, the id is dynamic depends on what the user click.
I would use sscanf
Untested example:
list($node_id, $pdf_id) = sscanf($url, "node/%d/pdf/%d");
$node_id contains the node id, $pdf_id contains the pdf id. According to your comment: Yes, you can output it with e.g. echo $pdf_id;.
If you need them both in an array, you can remove the list() method, doing it like this:
$ids = sscanf($url, "node/%d/pdf/%d");.
This returns an array with both node and pdf id in $ids.
Finally, if you just need the pdf id, you could do
$id = sscanf($url, "node/95/pdf/%d");.
I just showed how to fetch both because I assumed you may need both numbers from your url.
Edit
seeing all the other answers after posting my solution, I am wondering why everyone is solving this with multiple functions when there is a function available that does exactly what he needs: parsing a string according to a format. This also leads to less sql-injection prone code IMHO. And it doesn't break something when the url gets extended or query strings are appended.
Edit 2
list($node_id, $sub, $sub_id) = sscanf($url, "node/%d/%[^/]/%d"); will get you the "pdf" and it's id separate instead of "node/%d/%s/%d". This is because char / is also matched by %s. Using %[^/] matches everything except the forward slash.
You can do this:
$id = end(explode('/', 'node/95/pdf/1'));
Example:
$arr = explode('/', 'node/95/pdf/1');
$id = end($arr);
echo $id; // 1
$url = "node/95/pdf/1";
// Find the last occurence of a slash, get everything after that.
$id = substr($url, strrpos($url, "/") + 1 );
Try with:
$input = 'node/95/pdf/1';
$parts = explode('/', $input);
$output = (int) $parts[3];
I have this string:
a:3:{i:0;i:2;i:1;i:3;i:2;i:4;}
I want to get number between "a:" and ":{" that is "3".
I try to user substr and strpos but no success.
I'm newbie in regex , write this :
preg_match('/a:(.+?):{/', $v);
But its return me 1.
Thanks for any tips.
preg_match returns the number of matches, in your case 1 match.
To get the matches themselves, use the third parameter:
$matches = array();
preg_match(/'a:(\d+?):{/', $v, $matches);
That said, I think the string looks like a serialized array which you could deserialize with unserialize and then use count on the actual array (i.e. $a = count(unserialize($v));). Be careful with userprovided serialized strings though …
If you know that a: is always at the beginning of the string, the easiest way is:
$array = explode( ':', $string, 3 );
$number = $array[1];
You can use sscanfDocs to obtain the number from the string:
# Input:
$str = 'a:3:{i:0;i:2;i:1;i:3;i:2;i:4;}';
# Code:
sscanf($str, 'a:%d:', $number);
# Output:
echo $number; # 3
This is often more simple than using preg_match when you'd like to obtain a specific value from a string that follows a pattern.
preg_match() returns the number of times it finds a match, that's why. you need to add a third param. $matches in which it will store the matches.
You were not too far away with strpos() and substr()
$pos_start = strpos($str,'a:')+2;
$pos_end = strpos($str,':{')-2;
$result = substr($str,$pos_start,$pos_end);
preg_match only checks for appearance, it doesn't return any string.