Hello my output PHP code is :
Array ( [country] => BG - Bulgaria )
... and he comes from here :
<?php
$ip = $_SERVER['REMOTE_ADDR'];
print_r(geoCheckIP($ip));
//Array ( [domain] => dslb-094-219-040-096.pools.arcor-ip.net [country] => DE - Germany [state] => Hessen [town] => Erzhausen )
//Get an array with geoip-infodata
function geoCheckIP($ip)
{
//check, if the provided ip is valid
if(!filter_var($ip, FILTER_VALIDATE_IP))
{
throw new InvalidArgumentException("IP is not valid");
}
//contact ip-server
$response=#file_get_contents('http://www.netip.de/search?query='.$ip);
if (empty($response))
{
throw new InvalidArgumentException("Error contacting Geo-IP-Server");
}
//Array containing all regex-patterns necessary to extract ip-geoinfo from page
$patterns=array();
$patterns["country"] = '#Country: (.*?) #i';
//Array where results will be stored
$ipInfo=array();
//check response from ipserver for above patterns
foreach ($patterns as $key => $pattern)
{
//store the result in array
$ipInfo[$key] = preg_match($pattern,$response,$value) && !empty($value[1]) ? $value[1] : '';
}
return $ipInfo;
}
?>
How can I get ONLY the name of the Country like in my case "Bulgaria"? I think it will happen with preg_replace or substr but i dont know what is the better solution now.
substr's probably easiest:
$bad_country = 'BG - Bulgaria';
$good_country = substr($bad_country, 5); // start at char 5, 'B'
if the country is always separated from the acronym by ' - ', do it like this:
list($acrn, $country) = explode(' - ', $var);
If you are guaranteed that the output will always be in the same format(ie BG - Bulgaria, US - United States, etc), you could use explode():
$array['country'] = "BG - Bulgaria";
$country = explode(" - ", $array['country']);
echo $country[1];
This will output "Bulgaria".
try:
foreach( $list as $v) {
$temp = explode(' - ', $v);
$countries[] = $temp[1];
}
$patterns["country"] = '#Country:.*-\s+(\w+?) #i';
try this one as your pattern
Change your pattern to this:
'#Country: [a-z]{2,} - (.*?) #i'
Assuming the pattern won't change
Related
I have string like this
$string = 'title,id,user(name,email)';
and I want result to be like this
Array
(
[0] => title
[1] => id
[user] => Array
(
[0] => name
[1] => email
)
)
so far I tried with explode function and multiple for loop the code getting ugly and i think there must be better solution by using regular expression like preg_split.
Replace the comma with ### of nested dataset then explode by a comma. Then make an iteration on the array to split nested dataset to an array. Example:
$string = 'user(name,email),office(title),title,id';
$string = preg_replace_callback("|\(([a-z,]+)\)|i", function($s) {
return str_replace(",", "###", $s[0]);
}, $string);
$data = explode(',', $string);
$data = array_reduce($data, function($old, $new) {
preg_match('/(.+)\((.+)\)/', $new, $m);
if(isset($m[1], $m[2]))
{
return $old + [$m[1] => explode('###', $m[2])];
}
return array_merge($old , [$new]);
}, []);
print '<pre>';
print_r($data);
First thanks #janie for enlighten me, I've busied for while and since yesterday I've learnt a bit regular expression and try to modify #janie answer to suite with my need, here are my code.
$string = 'user(name,email),title,id,office(title),user(name,email),title';
$commaBetweenParentheses = "|,(?=[^\(]*\))|";
$string = preg_replace($commaBetweenParentheses, '###', $string);
$array = explode(',', $string);
$stringFollowedByParentheses = '|(.+)\((.+)\)|';
$final = array();
foreach ($array as $value) {
preg_match($stringFollowedByParentheses, $value, $result);
if(!empty($result))
{
$final[$result[1]] = explode('###', $result[2]);
}
if(empty($result) && !in_array($value, $final)){
$final[] = $value;
}
}
echo "<pre>";
print_r($final);
I have the following array.
$state = array("gujarat","andhra_pradesh","madhya_pradesh","uttar_pradesh");
Expected Output
$state = array("Gujarat","Andhra Pradesh","Madhya Pradesh","Uttar Pradesh");
I want to convert array values with each first character of a word with UpperCase and replace _ with space. So I do it using this loop and it working as expected.
foreach($states as &$state)
{
$state = str_replace("_"," ",$state);
$state = ucwords($state);
}
But my question is: is there any PHP function to convert the whole array as per my requirement?
You can use the array_map function.
function modify($str) {
return ucwords(str_replace("_", " ", $str));
}
Then in just use the above function as follows:
$states=array_map("modify", $old_states)
Need to use array_map function like as
$state = array("gujarat","andhra_pradesh","madhya_pradesh","uttar_pradesh");
$state = array_map(upper, $state);
function upper($state){
return str_replace('_', ' ', ucwords($state));
}
print_r($state);// output Array ( [0] => Gujarat [1] => Andhra pradesh [2] => Madhya pradesh [3] => Uttar pradesh )
PHP's array_map can apply a callback method to each element of an array:
$state = array_map('makePretty', $state);
function makePretty($value)
{
$value= str_replace("_"," ",$value);
return ucwords($value);
}
Use array_map() function
<?php
function fun($s)
{
$val = str_replace("_"," ",$s);
return ucwords($val);
}
$state = array("gujarat","andhra_pradesh","madhya_pradesh","uttar_pradesh");
$result = array_map('fun',$state);
print_r($result);
?>
So I have the following string:
{family:Open Sans,name:Open Sans,import_family:Open+Sans:300,300italic,regular,italic,600,600italic,700,700italic,800,800italic,classname:opensans}
I'd like to "vectorize" it, so maybe it would look something like this:
XX['family'] = "Open Sans',
XX['name'] = 'Open Sans',
XX['import_family'] = 'Open+Sans:300,300italic,regular,italic,600,600italic,700,700italic,800,800italic',
XX['classname'] = 'opensans';
Any ideas on how I could achieve this in PHP? It's getting on my nerves, been trying to work it out with regular expressions for the last couple of hours with no results so far.
Thanks in advance!
Here is a simple parser for this format you could use. It will handle all fields and values and return them as a key/value array. It assumes that the string starts and ends with curly braces and uses the field:optional:optional,a,b,c format.
<?php
header('Content-Type: text/plain');
function parse($str) {
$obj = [];
$str = substr($str, 1, -1);
$candidates = explode(',', $str);
$lastKey = null;
foreach ($candidates as $candidate) {
if (strpos($candidate, ':')) {
$parts = explode(':', $candidate);
$key = $parts[0];
$value = substr($candidate, strlen($key) + 1);
$obj[$key] = $value;
$lastKey = $key;
} else {
$obj[$lastKey] .= ',' . $candidate;
}
}
return $obj;
}
$example = '{family:Open Sans,name:Open Sans,import_family:Open+Sans:300,300italic,regular,italic,600,600italic,700,700italic,800,800italic,classname:opensans}';
print_r(parse($example));
?>
Output from the example string you specified:
Array
(
[family] => Open Sans
[name] => Open Sans
[import_family] => Open+Sans:300,300italic,regular,italic,600,600italic,700,700italic,800,800italic
[classname] => opensans
)
Try this:
$s = "{family:Open Sans,name:Open Sans,import_family:Open+Sans:300,300italic,regular,italic,600,600italic,700,700italic,800,800italic,classname:opensans}";
$s = rtrim(ltrim($s, '{'), '}');
preg_match_all('#([^:,]+):((?:(?!(,[^:,]+:)).)*)#', $s, $matches);
$vector = array_combine($matches[1], $matches[2]);
EDIT
As HamZa explains here, a shorter regular expression is:
([^:,]+):(.+?)(?=,[^,]+:|$)
How can i find if a string has subdomain existing if there is no scheme / host present.
eg: $url="sub.main.com/images/sample.jpg";
I am trying to parse the url for images, and I am using parse_url for most cases.
But given the url strings can some in different flavors,
eg:
/images/sample.jpg
//main.com/images/sample.jpg
images/sample.jpg
etc, I am trying to address the different cases one by one. Right now, I am finding it hard to detect if a string has subdomain present or not.
so for a string such as $url="sub.main.com/images/sample.jpg";` i would like to extract the subdomain, and for a string such as images/sample.jpg, i would like to find out that there is no subdomain
Interesting problem. I've fiddled around with this for a while; this method inevitably isn't perfect, but it may start you down the right path.
My solution begins with the two source files in this repository: https://github.com/usrflo/registered-domain-libs/tree/master/PHP
First, you may need to modify regDomain.inc.php to change an instance of $signingDomainParts = split('\.', $signingDomain); to $signingDomainParts = preg_split('/\./', $signingDomain); if split is deprecated in your php version.
Once you've got those saved, try this testing code, I put all of the URLs mentioned in the thread here as test cases:
<?php
require_once("effectiveTLDs.inc.php");
require_once("regDomain.inc.php");
$tests = Array("/images/sample.jpg","//main.com/images/sample.jpg","images/sample.jpg", "sub.main.com/images/sample.jpg", "http://www.example.com/www.google.com/sample.jpg", "amazon.co.uk/images/sample.jpg", "amazon.com/images/sample.jpg", "http://sub2.sub.main.co.uk/images/sample.jpg", "sub2.sub.main.co.uk/images/sample.jpg");
foreach($tests as $test)
{
echo "Attempting $test.<BR/>";
$one = parse_url($test);
if(!array_key_exists("host", $one))
{
echo "Converting to: http://$test";
echo "<BR/>";
$one = parse_url("http://$test");
}
if(!$one){echo "<BR/>";continue;}
echo "parse_url parts: ";
print_r($one);
echo "<BR/>";
if($one && array_key_exists("host", $one))
{
$domain = getRegisteredDomain($one["host"], $tldTree);
if(sizeof($domain))
{
$two = explode(".", $domain);
echo "domain parts: ";
print_r($two);
echo "<BR/>";
if(sizeof($two))
{
$three = array_diff(explode(".", $one["host"]), $two);
if(sizeof($three))
{
echo "Hark! A subdomain!: ";
print_r($three);
echo "<BR/>";
}
}
}
}
echo "<BR/>";
}
?>
This code identifies the following of the test-cases as having subdomains:
Attempting sub.main.com/images/sample.jpg.
Hark! A subdomain!: Array ( [0] => sub )
Attempting http://www.example.com/www.google.com/sample.jpg.
Hark! A subdomain!: Array ( [0] => www )
Attempting http://sub2.sub.main.co.uk/images/sample.jpg.
Hark! A subdomain!: Array ( [0] => sub2 [1] => sub )
Attempting sub2.sub.main.co.uk/images/sample.jpg.
Hark! A subdomain!: Array ( [0] => sub2 [1] => sub )
Try this code
<?php
$url = 'sub.main.com/images/sample.jpg';
$arr = explode('/',$url);
$domain = $arr[0];
$string = $arr[1];
$arr2 = explode('.',$domain);
if(count($arr2)>2) {
$subdomain = $arr2[0];
echo $subdomain;
}
?>
<?php
$url = 'http://sub.main.com/images/sample.jpg';
$arr = explode('/',$url);
$pieces = parse_url($url);
$domain = isset($pieces['host']) ? $pieces['host'] : '';
if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs))
{
$main_domain=$regs['domain'];
}
$host=$pieces['host'];
$path=$pieces['path'];
if($host != $main_domain)
{
$arr2 = explode('.',$host);
$subdomain = $arr2[0];
echo $subdomain;
}
$string=substr($path,1,strlen($path));
?>
Try the following:
<?php
$url="sub.main.com/images/sample.jpg";
preg_match('#^(?:http://)?([^.]+).?([^/]+)#i',$url, $hits);
print_r($hits);
?>
This should output something like:
Array ( [0] => sub.main.com [1] => sub [2] => main.com )
I'd like to get some values out of an array and print them out on the page.
For [1], these things should be extracted: USD 7.0269 6.4119 0.14231 0.15596
The array looks like this:
print_r($arr);
[1] => USD United States of America 7.0269 6.4119 Dollars 0.14231 0.15596 � Copyright 2003-2011. Powered by CurrencyXchanger 3.580
[2] => EUR Euro Member Countries 9.0373 8.3253 Euro 0.1107 0.1201 � Copyright 2003-2011. Powered by CurrencyXchanger 3.580
What is the best solution to accomplish this?
I'd use preg_match_all() after I trim off the area of interest:
foreach ($arr as $line) {
// currency is in the first four characters (apparently)
$currency = substr($line, 0, 4);
// we use everything left of 'Copyright'
$rest = strstr($line, 'Copyright', true);
// match each occurrence of nn.nnnn
if (preg_match_all('/\d+\.\d+/', $rest, $matches)) {
// $matches[0] contains all the amounts
echo $currency, ' ', join(' ', $matches[0]), PHP_EOL;
}
}
For PHP < 5.2 you need this line to calculate $rest:
$rest = substr($line, 0, strpos($line, 'Copyright'));
Demo
Here is a regex solution:
foreach($arr as $key => $item)
{
preg_match('/^([A-Z]){3}[\sA-Za-z]+(\d+\.\d+)\s+(\d+\.\d+)\s+[A-Za-z]+\s+(\d+\.\d+)\s+(\d+\.\d+)/', $item, $matches);
$result[$key] = array_shift($matches);
}
The regex corresponds to your pattern and captures everything you want inside consecutive elements of $matches. Since $matches[0] represents the full match, we remove the first element and assign it to your result array.
Try
foreach($arr as $v) {
$items = explode(' ', $v);
$new_arr[] = $items[0]; //Getting the currency type
foreach($items as $k => $m) {
if(is_numeric($m) && floor($m) != $m && $k != (count($items) - 1))
$new_arr[] = $m;
}
}
//displaying the $new_arr
foreach($new_arr as $n) {
if(is_numeric($n) === FALSE)
echo "\n";
echo $n . ' ';
}
See it in action here
Done quickly:
$result = array_map(
function ($string) {
preg_match_all('/(\d+\.\d+)\s/', $string, $matches);
return substr($string, 0, 3) . ' ' . implode(' ', $matches[1]);
},
$arr
);
Result:
Array
(
[0] => USD 7.0269 6.4119 0.14231 0.15596
[1] => EUR 9.0373 8.3253 0.1107 0.1201
)
With Regular Expressions you can get it.
foreach($arr as $key => $value) {
preg_match_all('/(\d+\.\d+)/', $value, $matches);
$result[substr($value, 0, 3)] = array_shift($matches);
}
You get an Array like this
var_dump($result);
array (
'USD' => array( 7.0269, 6.4119, 0.14231, 0.15596 )
'EUR' => array( 9.0373, 8.3253, 0.1107, 0.1201 )
)