Converting visually formatted plain text output to array - php

I am using Virtualmin and testing out the Remote API PHP features for a project. I can't seem to find any good documentation on this so I am testing out different functions randomly.
Making an API call is done like this:
<?php
$result = shell_exec("wget -O - --quiet --http-user=root --http-passwd=pass --no-check-certificate 'https://localhost:10000/virtual-server/remote.cgi?program=list-users&domain=testdomain.co.uk'");
echo $result;
?>
The issue I am facing is the result output is plain text formatted in a way which is easily readable. I have provided an example image below. I have tried using explode to create an array which is easily manageable but I cannot explode by blank space as parts such as "real name" or the actual real names have spaces? This also seems to output tens of empty array parts [1] => [2] => [3] => [4] => [5] =>
This is what I currently have which is providing numerous empty array values.
$lines = explode("\n", $result);
$out = array();
foreach ($lines as $line) {
$parts = explode(" ", $line);
}
Ideally I would like the array to work like a multidimensional array.

Related

preg match to get text after # symbol and before next space using php

I need help to find out the strings from a text which starts with # and till the next immediate space by preg_match in php
Ex : I want to get #string from this line as separate.
In this example, I need to extract "#string" alone from this line.
Could any body help me to find out the solutions for this.
Thanks in advance!
PHP and Python are not the same in regard to searches. If you've already used a function like strip_tags on your capture, then something like this might work better than the Python example provided in one of the other answers since we can also use look-around assertions.
<?php
$string = <<<EOT
I want to get #string from this line as separate.
In this example, I need to extract "#string" alone from this line.
#maybe the username is at the front.
Or it could be at the end #whynot, right!
dog#cat.com would be an e-mail address and should not match.
EOT;
echo $string."<br>";
preg_match_all('~(?<=[\s])#[^\s.,!?]+~',$string,$matches);
print_r($matches);
?>
Output results
Array
(
[0] => Array
(
[0] => #string
[1] => #maybe
[2] => #whynot
)
)
Update
If you're pulling straight from the HTML stream itself, looking at the Twitter HTML it's formatted like this however:
<s>#</s><b>UserName</b>
So to match a username from the html stream you would match with the following:
<?php
$string = <<<EOT
<s>#</s><b>Nancy</b> what are you on about?
I want to get <s>#</s><b>string</b> from this line as separate. In this example, I need to extract "#string" alone from this line.
<s>#</s><b>maybe</b> the username is at the front.
Or it could be at the end <s>#</s><b>WhyNot</b>, right!
dog#cat.com would be an e-mail address and should not match.
EOT;
$matchpattern = '~(<s>(#)</s><b\>([^<]+)</b>)~';
preg_match_all($matchpattern,$string,$matches);
$users = array();
foreach ($matches[0] as $username){
$cleanUsername = strip_tags($username);
$users[]=$cleanUsername;
}
print_r($users);
Output
Array
(
[0] => #Nancy
[1] => #string
[2] => #maybe
[3] => #WhyNot
)
Just do simply:
preg_match('/#\S+/', $string, $matches);
The result is in $matches[0]

array_unique not working as expected in php

Here is a problem.
i am exploding a list of character by new line in an array. and doing array unique on it. but it is not working as expected.
below is code:
$list = "test
ok
test
test
ok
ok
test";
$list_explode = explode("\n", $list); //exploding the characters of the list from the input
//displaying unique
array_map('trim', $list_explode);
$result = array_unique($list_explode);
print_r($result);
The result is
Array ( [0] => test [1] => ok [6] => test )
use var_dump instead of print_r and you'll see there difference between the "test"s (take a look at codepad).
your code contains \r\n as linebreaks and you're splittoing at \n, so \r is still there at all entrys except the last one.
you're already using array_map to prevent this but forgot to use the retun-value (it doesn't work by reference) in the latter code. change that line to:
$list_explode = array_map('trim', $list_explode);
after doing this, you'll get what you expect (see at codepad again).
You've failed to take into account that your string has a sequence of \r\n for the line break. In exploding you've only removed the \n portion so what your result actually looks like is:
Array ( [0] => test\r [1] => ok [6] => test )
However, the \r does not print as a visible character (even though the code sees it).
You can split multiple lines of text in two main ways:
Use $list_explode = array_map('rtrim', explode("\n", $list));
Use $list_explode = preg_split("/\r?\n/", $list);

Dealing with commas in CSV

I get a CSV data from a SOAP call in php. Unfortunately, the data may have commas in it. It is formatted correctly as in
1,name,2,lariat,3,"first, last",5,NMEA,...
I need to parse it to individual values in either php or javascript. I have browsed through threads on stack overflow and elsewhere but have not found a specific solution in php / javascript.
The approach I am currently using is
$subject = '123,name,456,lryyrt,123213,"first,last",8585,namea3';
$pattern = '/,|,"/';
$t2=preg_replace ('/,|(".*")/','$0*',$subject);
$t2=str_replace(',','*',$t2);
$t2=str_replace('*',',',$t2);
Where * is the deliminator, but the preg_replace generates an extra *. I have tried a couple of other approaches involving preg_match and other preg_ functions but did not succeed in having any kind of a clean split.
Any suggestion on how to split up CSV data that contains commas in it?
Don't attempt to do this with a regular expression. Just use str_getcsv()! The third parameter informs str_getcsv() to look for quote-enclosed fields.
$subject = '123,name,456,lryyrt,123213,"first,last",8585,namea3';
$array = str_getcsv($subject, ",", '"');
print_r($array);
// Prints:
Array
(
[0] => 123
[1] => name
[2] => 456
[3] => lryyrt
[4] => 123213
[5] => first,last
[6] => 8585
[7] => namea3
)
Just another way to convert a csv file to an associative array.
<?php
//
// Convert csv file to associative array:
//
function csv_to_array($input, $delimiter=',')
{
$header = null;
$data = array();
$csvData = str_getcsv($input, "\n");
foreach($csvData as $csvLine){
if(is_null($header)) $header = explode($delimiter, $csvLine);
else{
$items = explode($delimiter, $csvLine);
for($n = 0, $m = count($header); $n < $m; $n++){
$prepareData[$header[$n]] = $items[$n];
}
$data[] = $prepareData;
}
}
return $data;
}
//-----------------------------------
//
//Usage:
$csvArr = csv_to_array(file_get_contents('test.csv'));
?>
For JavaScript use jQuery-CSV
If you're already using jQuery, just add the jquery-csv.js module to expose the extension methods. Then just convert the CSV directly to a JavaScript array.
If you're only parsing the following will convert it to a one-dimensional array:
$.csv.toArray(csv);
If you have a multi-line CSV string the following will convert it to a two-dimensional array:
$.csv.toArrays(csv);
Note: all the different line endings are detected and split correctly using a smart regex.
The default delimiter is a double-quote (") and the default separator is a comma (,) but you can change use custom settings by specifying them in the method call.
Ex:
$.csv.toArray(csv, {
separator:';',
delimiter:"'"
});
I created the project to provide an end-to-end CSV parser written in JavaScript that takes the guesswork out of importing-exporting CSV.
Doing the heavy lifting on the client removes unnecessary load on the server and removes any unnecessary AJAX round-trips to the server.
Update:
If you're looking for a server-side solution, the library also works on Node.js.

php convert string with new lines into array?

I am getting data from an API and the resulting string is
[RESPONSE]
PROPERTY[STATUS][0]=ACTIVE
PROPERTY[REGISTRATIONEXPIRATIONDATE][0]=2012-04-04 19:48:48
DESCRIPTION=Command completed successfully
QUEUETIME=0
CODE=200
RUNTIME=0.352
QUEUETIME=0
RUNTIME=0.8
EOF
I am trying to convert this into an array like
Array(
['PROPERTY[STATUS][0]'] => ACTIVE,
['CODE'] => 200,
...
);
So I am trying to explode it using the resulting file_get_content function with an explode like
$output = explode('=',file_get_contents($url));
But the problem is the returning values are not always returned in the same order, so I need to have it like $array['CODE'] = 200, and $array['RUNTIME'] = 0.352 however there does not seem to be any kind of new line characters? I tried \r\n, \n, <br>, \r\n\r\n in the explode function to no avail. But there is new lines in both notepad and the browser.
So my question is there some way to determine if a string is on a new line or determine what the character forcing the new line is? If not is there some other way I could read this into an array?
To find out what the breaking character is, you could do this (if $data contatins the string example you've posted):
echo ord($data[strlen('[RESPONSE]')]) . PHP_EOL;
echo ord($data[strlen('[RESPONSE]')+1]); // if there's a second char
Then take a look in the ASCII table to see what it is.
EDIT: Then you could explode the data using that newly found character:
explode(ord($ascii_value), $data);
Btw, does file() return a correct array?
Explode on "\n" with double quotes so PHP understands this is a line feed and not a backslashed n ;-) then explode each item on =
Why not just use parse_ini_file() or parse_ini_string()?
It should do everything you need (build an array) in one easy step.
Try
preg_split("/$/m", $str)
or
preg_split("/$\n?/m", $str)
for the split
The lazy solution would be:
$response = strtr($response, "\r", "\n");
preg_match_all('#^(.+)=(.+)\s*$#m', $response, $parts);
$parts = array_combine($parts[1], $parts[2]);
Gives you:
Array (
[PROPERTY[STATUS][0]] => ACTIVE
[PROPERTY[REGISTRATIONEXPIRATIONDATE][0]] => 2012-04-04 19:48:48
[DESCRIPTION] => Command completed successfully
[QUEUETIME] => 0
[CODE] => 200
[RUNTIME] => 0.8

How can I combine my two regular expressions and save the results as variable?

I get all the images with this
preg_match_all('!http://.+\.(?:jpe?g|png|gif)!Ui' , $content , $matches);
and this is how i block all the image if it has a "bad word"
'/(list|of|bad|words)/i'
How can I combine them and save the result instead in variable instead of print_r?
My purpose is to delete from content all those images and produce the "clean" content.
Thank you!
Probably the fastest way is to run the first regex and then filter out the bad ones later. You could probably do this with a callback rather easily. I wouldn't try to combine the regex though.
Might require some tweaking depending on how $content is formatted:
<?php
$content = 'http://www.example.com/images/image001.jpg
http://www.example.com/images/image002.jpeg
http://www.example.com/images/list001.jpg
http://www.example.com/images/image003.png
http://www.example.com/images/bad002.png
http://www.example.com/images/image004.gif
http://www.example.com/images/words003.jpg';
preg_match_all('!http://.+\.(?:jpe?g|png|gif)!Ui', $content, $matches);
preg_match_all('/\S+(list|of|bad|words)\S+/i', $content, $bads);
$filtered = array_values(array_diff($matches[0], $bads[0]));
print_r($filtered);
?>
Output:
Array
(
[0] => http://www.example.com/images/image001.jpg
[1] => http://www.example.com/images/image002.jpeg
[2] => http://www.example.com/images/image003.png
[3] => http://www.example.com/images/image004.gif
)

Categories