Reading information from CSS in PHP - php

I am creating a website where users shall be able to upload plugins with a file called 'info.css'. I want my PHP-file to be able to read out information from this file, for example the ID.
The 'info.css' file will contain something similar to:
/*
ID: test-preset;
Name: Test Preset;
*/
I want the ID and Name to get into separate strings, without the 'id:' or 'name:'.
Please write any solution you may will work. I have tried with following (but have gotten stuck on the way. Please note that the information in the 'info.css' file may appear in a different order, so for example it should work if the 'Name:' comes first.
$preset_inf = strtolower($preset_inf);
$preset_inf = explode('*/', $preset_inf);
$preset_inf = str_replace('/*', '', $preset_inf[0]);
$preset_inf = str_replace(' ', '', $preset_inf);
$preset_inf = explode(';', $preset_inf);

Regex?
$str = "/*
ID: test-preset;
Name: Test Preset;
*/";
preg_match_all("/(ID|Name):\s*(.*?)\;/s", $str, $m);
var_dump($m);
This will produce:
array(3) {
[0]=>
string(35) "ID: test-preset;
Name: Test Preset;"
[1]=>
string(11) "test-preset"
[2]=>
string(11) "Test Preset"
}
Matches anything between ID/Name and ;.
Edit noticed it could be the other way around too. Edited the code.
The output array will look slightly different but the part you want is in $m[2] array.
https://3v4l.org/iusmV

You can use regex to retrieve each variable, so:
preg_match( '/Name: (.*?);/', $css_file, $match );
$name = $match[1];
echo $name;
preg_match( '/ID: (.*?);/', $css_file, $match );
$id = $match[1];
echo $id;
Would return
Test Preset
test-preset

In case you need a more general solution, here is a regex that will parse a header with an arbitrary number of options along with their names:
$string = '/*
ID: test-preset;
Name: Test Preset;
*/';
$pattern = '/^(?!\/\*)([^:]+):([^:]+);$/mU';
preg_match_all($pattern, $string, $matches, PREG_SET_ORDER, 0);
$results = array();
foreach($matches as $match){
$results[$match[1]] = $match[2];
}
$results now contains an array with this structure:
[
"ID" => "test-preset",
"Name" => "Test Preset"
]
This has the benefit of being able to handle any number of "Header arguments".

Scalable solution.
$presetInfoItem = [];
$presetInfo = [];
$presetFile = "/*
ID: test-preset;
Name: Test Preset;
*/";
$fields = ['ID', 'Name'];
foreach ($fields as $field) {
$matchesCount = preg_match_all("#$field:(?'$field'[\w-\s]*);#", $presetFile, $presetInfoItem);
if ($matchesCount === 0 || $matchesCount === false) {
$presetInfo[$field] = "";
} else {
$presetInfo[$field] = trim($presetInfoItem[$field][0]);
}
}
var_export($presetInfo);

For your pleasure:
<?php
$css = '/*
ID: test-preset;
Name: Test Preset;
*/';
$css = str_replace("*/", "", $css);
$css = str_replace("/*", "", $css);
$css = str_replace(";", "", $css);
$css = trim($css);
$lines = explode("\n", str_replace("\r", '', $css));
if(!empty($lines)) {
foreach($lines as $i => $line) {
$vals = explode(":", $line);
$key = $vals[0];
$value = $vals[1];
echo '<div><b>'.$key.'</b>: '.$value.'</div>';
}
}
?>
Result is:
ID: test-preset
Name: Test Preset
Regex is not needed :)

Related

Read fails with spaces

I am very new to PHP and want to learn. I am trying to make a top-list for my server but I have a problem. My file is built like this:
"Name" "Kills"
"^0user1^7" "2"
"user2" "2"
"user3" "6"
"user with spaces" "91"
But if I want to read this with PHP it fails because the user has spaces.
That's the method I use to read the file:
$lines = file('top.txt');
foreach ($lines as $line) {
$parts = explode(' ', $line);
echo isset($parts[0]) ? $parts[0] : 'N/A' ;
}
Maybe someone knows a better method, because this don't work very well :D.
You need REGEX :-)
<?php
$lines = array(
'"^0user1^7" "2"',
'"user2" "2"',
'"user3" "6"',
'"user with spaces" "91"',
);
$regex = '#"(?<user>[a-zA-Z0-9\^\s]+)"\s"(?<num>\d+)"#';
foreach ($lines as $line) {
preg_match($regex, $line, $matches);
echo 'user = '.$matches['user'].', num = '.$matches['num']."\n";
}
In the regex, we have # delimiters, then look for stuff between quotes. Using (?PATTERN) gives you a named capture group. The first looks for letters etc, the second digits only.
See here to understand how the regex is matching!
https://regex101.com/r/023LlL/1/
See it here in action https://3v4l.org/qDVuf
For your process this might help
$lines = file('top.txt');
$line = explode(PHP_EOL, $lines); // this will split file content line by line
foreach ($line as $key=>$value_line ) {
echo str_replace(" ","",$value_line);
}
As I commented above, below is a simple example with JSON.
Assuming, you have stored records in JSON format:
$json = '{
"user1": "12",
"sad sad":"23"
}';
$decoded = json_decode($json);
foreach($decoded as $key => $value){
echo 'Key: ' . $key . ' And value is ' . $value;
}
And here is the demo link: https://3v4l.org/ih1P7

Get specific sentence of text files

I have the following text file :
====================================================================================
INDEXNUMARTICLE: '1997'
FILE: '###\www.kkk.com\kompas-pront\0004\25\economic\index.htm' NUMSENT: '22' DOMAIN: 'economic'
====================================================================================
2. Social change is a general term which refers to:
4. change in social structure: the nature, the social institutions.
6. When behaviour pattern changes in large numbers, and is visible and sustained, it results in a social change.
I wanna get only the sentence without the numbering and save it in database :
=========================================================================
= id = topic = content =
=========================================================================
= 1 = economic = Social change is a general term which refers to: =
= change in social structure: the nature, =
= the social institutions. When behaviour pattern =
= changes in large numbers, and is visible and sustained,
= it results in a social change. =
CODE
function isNumber($string) {
return preg_match('/^\\s*[0-9]/', $string) > 0;
}
$txt = "C:/Users/User/Downloads/economic.txt";
$lines = file($txt);
foreach($lines as $line_num => $line) {
$checkFirstChar = isNumber($line);
if ($checkFirstChar !== false) {
$line_parts = explode(' ', $line);
$line_number = array_shift($line_parts);
foreach ($line_parts as $part) {
if (empty($part)) continue;
$parts = array();
$string = implode(' ', $parts);
$query = mysql_query("INSERT INTO tb_file VALUES ('','economic','$string')");
}
}
}
I have the problem with array, the data that inserted in column content are words by words in different row. please help me. thank you :)
I think your idea is to complicated - try this short one:
$txt = "C:/Users/User/Downloads/economic.txt";
$lines = file($txt);
foreach($lines as $line_num => $line) {
$checkFirstChar = isNumber($line);
if ($checkFirstChar !== false) {
//entire text line without number
$string = substr($line,strpos($line,"")+1);
$query = mysql_query("INSERT INTO tb_file VALUES ('','economic','$string')");
}
}
Try this one, with regex.
$regex = "/[0-9]\. /";
$txt = "C:/Users/User/Downloads/economic.txt";
$str = file_get_contents($txt);
$index = -1;
//Find the first ocurrence of a number followed by '.' and a whitespace
if(preg_match($regex, $str, $matches, PREG_OFFSET_CAPTURE)) {
$index = $matches[0][1];
}
//Remove all the text before that first occurrence
$str = substr($str, $index);
//Replace all the occurrences of number followed by '. ' with ' '
$text = preg_replace($regex, " ", $str);

PHP Repalce text tags with another value that i have in array

I have this text:
$text = "Welcome {name}, this is your email address: {email}";
I want to replace the {name} and {email} tags at once, not one by one using str_replace("{name}","John",$text)
I already have the replace output this way:
$values_to_replace = array('name'=>'John','email'=>'blabla#gmail.com');
How to make it work to repalce whole text from one shot using the given $values_to_replace ?
Here are several ways:
First here is strtr(). It takes an key=>value array and replaces all occurences of key with value.
$values = array('name'=>'John','email'=>'blabla#gmail.com');
$text = "Welcome {name}, this is your email address: {email}";
$replacements = array();
foreach ($values as $name => $value) {
$replacements['{'.$name.'}'] = $value;
}
var_dump(strtr($text, $replacements));
Second str_replace() supports array for both the $search and $replace arguments.
$values = array('name'=>'John','email'=>'blabla#gmail.com');
$text = "Welcome {name}, this is your email address: {email}";
$search = array_map(
function($placeholder) {
return '{'.$placeholder.'}';
},
array_keys($values)
);
var_dump(str_replace($search, $values, $text));
The third option is interesting, if you like to handle all {something} occurrences. This requires a regular expression and logic so preg_replace_callback is needed.
$values = array('name'=>'John','email'=>'blabla#gmail.com');
$text = "Welcome {name}, this is your email address: {email}";
$replacer = function($match) use ($values) {
if (isset($values[$match['name']])) {
return $values[$match['name']];
} else {
return '';
}
};
var_dump(preg_replace_callback('(\\{(?P<name>[a-z\d]+)\\})i', $replacer, $text));
Since you can change the array keys to match the text to replace, then it's this easy:
$values_to_replace = array('{name}'=>'John','{email}'=>'blabla#gmail.com');
$text = str_replace(array_keys($values_to_replace), $values_to_replace, $text);
Or as Sébastien has shown.
To answer your comment, there are several ways, Sébastien's being one. Here's another:
$search = explode(',', '{'.implode('},{', array_keys($values_to_replace)).'}');
$text = str_replace($search, $values_to_replace, $text);
str_replace can take arrays as parameters:
$text = "Welcome {name}, this is your email address: {email}";
$from = array("{name}", "{email}");
$to = array("John", "blabla#gmail.com");
$new_text = str_replace( $from , $to, $text );

Extract subdomain / domain from a text file using php

I've the following code which extracts domain name from the input and stores them in an array
foreach ($output as $domList)
{
$extensionList = explode(",", "org,com,net");
$pattern = '/(\s{0,}|\.)([-a-z0-9]+\.(' . implode("|", $extensionList) . '))\s{1,}/i';
$matches = array();
preg_match_all($pattern, $domList, $matches);
}
matches[0] contains all domains extracted
How can i modify it to extract subdomains as well ?
Sample input and expected output would definitely help (I took creative license with the input). The idea in the new regex is to continue eating up anything that isn't .com,.org, or .net. Matches[0] should now yield all domains and subdomains.
$output = array("a" => " test.com test.sub.com", "b"=> "a.com a.b.com b.c.a.com" );
foreach ($output as $domList)
{
$extensionList = explode(",", "org,com,net");
$pattern = '/\s*([-a-z0-9]+\.)+' . implode("|", $extensionList) . '\s*/i';
$matches = array();
preg_match_all($pattern, $domList, $matches);
// foreach ($matches[0] as $val) {
// echo "matched: " . $val . "\n";
}
It shouldn't be difficult to tweak this to your needs.

PHP Remove URL from string

If I have a string that contains a url (for examples sake, we'll call it $url) such as;
$url = "Here is a funny site http://www.tunyurl.com/34934";
How do i remove the URL from the string?
Difficulty is, urls might also show up without the http://, such as ;
$url = "Here is another funny site www.tinyurl.com/55555";
There is no HTML present. How would i start a search if http or www exists, then remove the text/numbers/symbols until the first space?
I re-read the question, here is a function that would work as intended:
function cleaner($url) {
$U = explode(' ',$url);
$W =array();
foreach ($U as $k => $u) {
if (stristr($u,'http') || (count(explode('.',$u)) > 1)) {
unset($U[$k]);
return cleaner( implode(' ',$U));
}
}
return implode(' ',$U);
}
$url = "Here is another funny site www.tinyurl.com/55555 and http://www.tinyurl.com/55555 and img.hostingsite.com/badpic.jpg";
echo "Cleaned: " . cleaner($url);
Edit #2/#3 (I must be bored). Here is a version that verifies there is a TLD within the URL:
function containsTLD($string) {
preg_match(
"/(AC($|\/)|\.AD($|\/)|\.AE($|\/)|\.AERO($|\/)|\.AF($|\/)|\.AG($|\/)|\.AI($|\/)|\.AL($|\/)|\.AM($|\/)|\.AN($|\/)|\.AO($|\/)|\.AQ($|\/)|\.AR($|\/)|\.ARPA($|\/)|\.AS($|\/)|\.ASIA($|\/)|\.AT($|\/)|\.AU($|\/)|\.AW($|\/)|\.AX($|\/)|\.AZ($|\/)|\.BA($|\/)|\.BB($|\/)|\.BD($|\/)|\.BE($|\/)|\.BF($|\/)|\.BG($|\/)|\.BH($|\/)|\.BI($|\/)|\.BIZ($|\/)|\.BJ($|\/)|\.BM($|\/)|\.BN($|\/)|\.BO($|\/)|\.BR($|\/)|\.BS($|\/)|\.BT($|\/)|\.BV($|\/)|\.BW($|\/)|\.BY($|\/)|\.BZ($|\/)|\.CA($|\/)|\.CAT($|\/)|\.CC($|\/)|\.CD($|\/)|\.CF($|\/)|\.CG($|\/)|\.CH($|\/)|\.CI($|\/)|\.CK($|\/)|\.CL($|\/)|\.CM($|\/)|\.CN($|\/)|\.CO($|\/)|\.COM($|\/)|\.COOP($|\/)|\.CR($|\/)|\.CU($|\/)|\.CV($|\/)|\.CX($|\/)|\.CY($|\/)|\.CZ($|\/)|\.DE($|\/)|\.DJ($|\/)|\.DK($|\/)|\.DM($|\/)|\.DO($|\/)|\.DZ($|\/)|\.EC($|\/)|\.EDU($|\/)|\.EE($|\/)|\.EG($|\/)|\.ER($|\/)|\.ES($|\/)|\.ET($|\/)|\.EU($|\/)|\.FI($|\/)|\.FJ($|\/)|\.FK($|\/)|\.FM($|\/)|\.FO($|\/)|\.FR($|\/)|\.GA($|\/)|\.GB($|\/)|\.GD($|\/)|\.GE($|\/)|\.GF($|\/)|\.GG($|\/)|\.GH($|\/)|\.GI($|\/)|\.GL($|\/)|\.GM($|\/)|\.GN($|\/)|\.GOV($|\/)|\.GP($|\/)|\.GQ($|\/)|\.GR($|\/)|\.GS($|\/)|\.GT($|\/)|\.GU($|\/)|\.GW($|\/)|\.GY($|\/)|\.HK($|\/)|\.HM($|\/)|\.HN($|\/)|\.HR($|\/)|\.HT($|\/)|\.HU($|\/)|\.ID($|\/)|\.IE($|\/)|\.IL($|\/)|\.IM($|\/)|\.IN($|\/)|\.INFO($|\/)|\.INT($|\/)|\.IO($|\/)|\.IQ($|\/)|\.IR($|\/)|\.IS($|\/)|\.IT($|\/)|\.JE($|\/)|\.JM($|\/)|\.JO($|\/)|\.JOBS($|\/)|\.JP($|\/)|\.KE($|\/)|\.KG($|\/)|\.KH($|\/)|\.KI($|\/)|\.KM($|\/)|\.KN($|\/)|\.KP($|\/)|\.KR($|\/)|\.KW($|\/)|\.KY($|\/)|\.KZ($|\/)|\.LA($|\/)|\.LB($|\/)|\.LC($|\/)|\.LI($|\/)|\.LK($|\/)|\.LR($|\/)|\.LS($|\/)|\.LT($|\/)|\.LU($|\/)|\.LV($|\/)|\.LY($|\/)|\.MA($|\/)|\.MC($|\/)|\.MD($|\/)|\.ME($|\/)|\.MG($|\/)|\.MH($|\/)|\.MIL($|\/)|\.MK($|\/)|\.ML($|\/)|\.MM($|\/)|\.MN($|\/)|\.MO($|\/)|\.MOBI($|\/)|\.MP($|\/)|\.MQ($|\/)|\.MR($|\/)|\.MS($|\/)|\.MT($|\/)|\.MU($|\/)|\.MUSEUM($|\/)|\.MV($|\/)|\.MW($|\/)|\.MX($|\/)|\.MY($|\/)|\.MZ($|\/)|\.NA($|\/)|\.NAME($|\/)|\.NC($|\/)|\.NE($|\/)|\.NET($|\/)|\.NF($|\/)|\.NG($|\/)|\.NI($|\/)|\.NL($|\/)|\.NO($|\/)|\.NP($|\/)|\.NR($|\/)|\.NU($|\/)|\.NZ($|\/)|\.OM($|\/)|\.ORG($|\/)|\.PA($|\/)|\.PE($|\/)|\.PF($|\/)|\.PG($|\/)|\.PH($|\/)|\.PK($|\/)|\.PL($|\/)|\.PM($|\/)|\.PN($|\/)|\.PR($|\/)|\.PRO($|\/)|\.PS($|\/)|\.PT($|\/)|\.PW($|\/)|\.PY($|\/)|\.QA($|\/)|\.RE($|\/)|\.RO($|\/)|\.RS($|\/)|\.RU($|\/)|\.RW($|\/)|\.SA($|\/)|\.SB($|\/)|\.SC($|\/)|\.SD($|\/)|\.SE($|\/)|\.SG($|\/)|\.SH($|\/)|\.SI($|\/)|\.SJ($|\/)|\.SK($|\/)|\.SL($|\/)|\.SM($|\/)|\.SN($|\/)|\.SO($|\/)|\.SR($|\/)|\.ST($|\/)|\.SU($|\/)|\.SV($|\/)|\.SY($|\/)|\.SZ($|\/)|\.TC($|\/)|\.TD($|\/)|\.TEL($|\/)|\.TF($|\/)|\.TG($|\/)|\.TH($|\/)|\.TJ($|\/)|\.TK($|\/)|\.TL($|\/)|\.TM($|\/)|\.TN($|\/)|\.TO($|\/)|\.TP($|\/)|\.TR($|\/)|\.TRAVEL($|\/)|\.TT($|\/)|\.TV($|\/)|\.TW($|\/)|\.TZ($|\/)|\.UA($|\/)|\.UG($|\/)|\.UK($|\/)|\.US($|\/)|\.UY($|\/)|\.UZ($|\/)|\.VA($|\/)|\.VC($|\/)|\.VE($|\/)|\.VG($|\/)|\.VI($|\/)|\.VN($|\/)|\.VU($|\/)|\.WF($|\/)|\.WS($|\/)|\.XN--0ZWM56D($|\/)|\.XN--11B5BS3A9AJ6G($|\/)|\.XN--80AKHBYKNJ4F($|\/)|\.XN--9T4B11YI5A($|\/)|\.XN--DEBA0AD($|\/)|\.XN--G6W251D($|\/)|\.XN--HGBK6AJ7F53BBA($|\/)|\.XN--HLCJ6AYA9ESC7A($|\/)|\.XN--JXALPDLP($|\/)|\.XN--KGBECHTV($|\/)|\.XN--ZCKZAH($|\/)|\.YE($|\/)|\.YT($|\/)|\.YU($|\/)|\.ZA($|\/)|\.ZM($|\/)|\.ZW)/i",
$string,
$M);
$has_tld = (count($M) > 0) ? true : false;
return $has_tld;
}
function cleaner($url) {
$U = explode(' ',$url);
$W =array();
foreach ($U as $k => $u) {
if (stristr($u,".")) { //only preg_match if there is a dot
if (containsTLD($u) === true) {
unset($U[$k]);
return cleaner( implode(' ',$U));
}
}
}
return implode(' ',$U);
}
$url = "Here is another funny site badurl.badone somesite.ca/worse.jpg but this badsite.com www.tinyurl.com/55555 and http://www.tinyurl.com/55555 and img.hostingsite.com/badpic.jpg";
echo "Cleaned: " . cleaner($url);
returns:
Cleaned: Here is another funny site badurl.badone but this and and
$string = preg_replace('/\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|$!:,.;]*[A-Z0-9+&##\/%=~_|$]/i', '', $string);
Parsing text for URLs is hard and looking for pre-existing, heavily tested code that already does this for you would be better than writing your own code and missing edge cases. For example, I would take a look at the process in Django's urlize, which wraps URLs in anchors. You could port it over to PHP, and--instead of wrapping URLs in an anchor--just delete them from the text.
thanks mike,
update a bit, it return notice error,
'/\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|$!:,.;]*[A-Z0-9+&##\/%=~_|$]/i'
$string = preg_replace('/\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|$!:,.;]*[A-Z0-9+&##\/%=~_|$]/i', '', $string);
$url = "Here is a funny site http://www.tunyurl.com/34934";
$replace = 'http www .com .org .net';
$with = '';
$clean_url = clean($url,$replace,$with);
echo $clean_url;
function clean($url,$replace,$with) {
$replace = explode(" ",$replace);
$new_string = '';
$check = explode(" ",$url);
foreach($check AS $key => $value) {
foreach($replace AS $key2 => $value2 ) {
if (-1 < strpos( strtolower($value), strtolower($value2) ) ) {
$value = $with;
break;
}
}
$new_string .= " ".$value;
}
return $new_string;
}
You would need to write a regular expression to extract out the urls.

Categories