explode function not working properly - php

$filename = 'itunes_report.txt';
$f = fopen($filename, 'r');
$db = array();
$dbSize = 0;
$var = file($filename);
$mydata = trim($var[1]);
$temp = explode(" ", $mydata);
print_r($temp);
i read data from a file using this code. i was take the first line from the text file.
this is the line
APPLE US ebookReaderipad EC Media (International) Pvt. ltd BooksOnwink 1.3 1F 1 0 07/30/2012 08/05/2012 GBP GB GBP 425105344 0
i explode this line using white spaces. Then some white spaces are missing in output.
out put
Array ( [0] => APPLE US ebookReaderipad EC [1] => Media [2] => (International) [3] => Pvt. [4] => ltd BooksOnwink 1.3 1F 1 0 07/30/2012 08/05/2012 GBP GB GBP 425105344 0 )

Your input seem to be is tab \t delimited, you can split on "\t":
$temp = explode("\t", $mydata);
or if you are really mean to split on every whitespace, try using a more flexible spit with regexps:
$temp = preg_split('/\s+/', $mydata);
This will split on everything considered whitespace and consume sequence of whitespaces too.

Related

How to read columns from text file and insert in database php

I have a text file with multiple rows and columns inside them.
I want to read each and every row and column, store them in array and save all data in database using cakephp.
Below is my code, I wrote some row and column reading logic which i wants to implement.
Please help me to do this critical thing.
public function importfile(){
$fp = 'C:/wamp64/www/jhraut/webroot/uploads/120518SU';
$handle = fopen($fp, "r");
if ($handle) {
while (($line = fgetc($handle)) !== false) {
$data['GunNo'] = "first 5 characters of $line is GunNo than 1 character is space";
$data['FatGun'] = "Second 3 characters of $line is FatGun than 1 character is space";
$data['LoinGun'] = "Third 3 characters of $line is LoinGun than 1 character is space";
$data['ScaleWt'] = "fourth 5 characters of $line is ScaleWt than 1 character is space";
$data['Partial'] = "if P or M than 1 character is space";
$data['TimeofReading'] = "last 8 characters of $line is TimeofReading";
echo $line;
}
$this->Event_program->saveAll($data);
}
fclose($fp);
exit;
}
My file data
parti 011 058 145.6 P 06:37:01
00002 016 049 175.8 06:37:08
00003 009 072 150.8 06:37:15
00004 009 053 146.8 06:37:22
00005 011 054 169 06:37:29
00006 009 052 152.4 06:37:37
00007 018 059 194.8 06:37:44
00008 009 060 139.4 06:37:51
parti 008 069 134.8 P 06:37:58
00010 023 054 194.2 06:38:05
miss 197.2 06:38:13
00011 023 052 150 06:38:20
00012 008 059 146.6 06:38:27
00013 010 067 156 06:38:34
00014 013 049 190.8 06:38:41
Try something like this:
// set path to file
$file = WWW_ROOT.'uploads/120518SU';
// check if file exists
if (file_exists($file)) {
// Reads an entire file into an array with file() method
// and loop array
foreach (file($file) as $line) {
// convert line value to new array
$arr = explode(' ', $line);
// do something with your data..
$data = [
'GunNo' => $arr[0],
// ...
];
$entity = $this->EventProgram->newEntity($data);
$this->EventProgram->save($entity);
}
}
Update with some test:
$line = '00003 009 072 150.8 06:37:15';
$arr = explode(' ', $line);
print_r($arr);
// output
Array
(
[0] => 00003
[1] => 009
[2] => 072
[3] => 150.8
[4] =>
[5] =>
[6] =>
[7] => 06:37:15
)
$line = 'parti 008 069 134.8 P 06:37:58';
// ..
Array
(
[0] => parti
[1] => 008
[2] => 069
[3] => 134.8
[4] => P
[5] =>
[6] => 06:37:58
)
Then:
// do something with your data..
$data = [
// ...
'TimeofReading' => end($arr),
];
Update: reading as csv file
Use fgetcsv()
The fgetcsv() function parses a line from an open file, checking for
CSV fields.
The fgetcsv() function stops returning on a new line, at the specified
length, or at EOF, whichever comes first.
This function returns the CSV fields in an array on success, or FALSE
on failure and EOF.
fgetcsv(file,length,separator,enclosure);
Use regular expression. As you have some rows having few fields empty splitting with space might cause problem.
preg_match('/(.{5}) (.{3}) (.{3}) (.{5}) (.{1}) (.{8})/', $line, $op);
$data['GunNo'] = $op[1];
$data['FatGun'] = $op[2];
$data['LoinGun'] = $op[3];
$data['ScaleWt'] = $op[4];
$data['Partial'] = $op[5];
$data['TimeofReading'] = $op[6];
echo $op[0];
You can teds regular expression line on
https://www.phpliveregex.com/#tab-preg-match

Split string into array regex php

I need to split the string bellow into array keys like in this format:
string = "(731) some text here with number 2 (220) some 54 number other text here" convert into:
array(
'731' => 'some text here with number 2',
'220' => 'some 54 number other text here'
);
I have tried:
preg_split( '/\([0-9]{3}\)/', $string );
and got:
array (
0 => 'some text here',
1 => 'some other text here'
);
Code
$string = "(731) some text here with number 2 (220) some 54 number other text here";
preg_match_all("/\((\d{3})\) *([^( ]*(?> +[^( ]+)*)/", $string, $matches);
$result = array_combine($matches[1], $matches[2]);
var_dump($result);
Output
array(2) {
[731]=>
string(28) "some text here with number 2"
[220]=>
string(30) "some 54 number other text here"
}
ideone demo
Description
The regex uses
\((\d{3})\) to match 3 digits in parentheses and captures it (group 1)
\ * to match the spaces in between keys and values
([^( ]*(?> +[^( ]+)*) to match everything except a ( and captures it (group 2)
This subpattern matches exactly the same as [^(]*(?<! ) but more efficiently, based on the unrolling-the-loop technique.
*Notice though that I am interpreting a value field cannot have a ( within. If that is not the case, do tell and I will modify it accordingly.
After that, we have $matches[1] with keys and $matches[2] with values. Using array_combine() we generate the desired array.
Try this:
$string = "(731) some text here with number 2 (220) some 54 number other text here";
$a = preg_split('/\s(?=\()/', $string);//split by spaces preceding the left bracket
$res = array();
foreach($a as $v){
$r = preg_split('/(?<=\))\s/', $v);//split by spaces following the right bracket
if(isset($r[0]) && isset($r[1])){
$res[trim($r[0],'() ')] = trim($r[1]);//trim brackets and spaces
}
}
print_r($res);
Output:
Array
(
[731] => some text here with number 2
[220] => some 54 number other text here
)
DEMO
If you want to limit it only to those numbers in brackets that have 3 digits, just modify the lookarounds:
$a = preg_split('/\s(?=\([0-9]{3}\))/', $string);
you can try this one,
<?php
$str="(731) some text here (220) some other text here";
echo $str .'<br>';
$arr1=explode('(', $str);
$size_arr=count($arr1);
$final_arr=array();
for($i=1;$i<$size_arr; $i++){
$arr2=explode(')', $arr1[$i]);
$final_arr[$arr2[0]]=trim($arr2[1]);
}
echo '<pre>';
print_r($final_arr);
?>
Use this link to test the code, Click Here.
I try to use the simple syntax. Hope everybody can understand.
I'm pretty sure that defining the keys is not possible, as the regex will add matches coninuously.
I would define 2 regex,
one for the keys:
preg_match_all("/(\()([0-9]*)(\))\s/", $input_lines, $output_array);
you will find your keys in $output_array[2].
And one for the texts (that looks quite the same):
preg_split("/(\()([0-9]*)(\))\s/", $input_line);
After that, you can build your custom array iterating over both.
Make sure to trim the strings in the second array when inserting.
Using preg_replace_callback() you can quickly achieve what you desire (when only parentheses contain 3 digits):
$string = "(731) some text here with number 2 (220) some 54 number other text here";
$array = array();
preg_replace_callback('~(\((\d{3})\))(.*?)(?=(?1)|\Z)~s', function($match) use (&$array) {
$array[$match[2]] = trim($match[3]);
}, $string);
var_dump($array);
Output:
array(2) {
[731]=>
string(28) "some text here with number 2"
[220]=>
string(30) "some 54 number other text here"
}
Maybe you can add PREG_SPLIT_DELIM_CAPTURE flag to preg_split. From preg_split man page (http://php.net/manual/en/function.preg-split.php)
PREG_SPLIT_DELIM_CAPTURE
If this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well.
So if you change your code to:
$results = preg_split('/\(([0-9]+)\)/s', $data,null,PREG_SPLIT_DELIM_CAPTURE);
You will obtain an array similar to:
Array
(
[0] => KS/M/ 2013/1238
[1] => 220
[2] => 23/12/2013
[3] => 300
[4] =>
[5] => 731
[6] => VALDETE BUZA ADEM JASHARI- PRIZREN, KS
[7] => 526
[8] =>
[9] => 591
[10] =>
[11] => 740
[12] =>
[13] => 540
[14] => DEINA
[15] => 546
[16] =>
[17] => 511
[18] => 3 Preparatet për zbardhim dhe substancat tjera për larje rrobash; preparatet për pastrim, shkëlqim, fërkim dhe gërryerje; sapunët; parfumet, vajrat esencialë, preparatet kozmetike, losionet për flokë, pasta për dhembe
14 Metalet e cmueshme dhe aliazhet e tyre; mallrat në metale të cmueshme ose të veshura me to, që nuk janë përfshire në klasat tjera; xhevahirët, gurët e cmueshëm; instrumentet horologjike dhe kronometrike (për matjen dhe regjistrimin e kohës)
25 Rrobat, këpucët, kapelat
35 Reklamim, menaxhim biznesi; administrim biznesi; funksione zyre
)
What you should do is to loop over the array ignoring first element in that case:
$myArray = array();
$myKey = '';
foreach ($results as $k => $v) {
if ( ($k > 0) && ($myKey == '')) {
$myKey = $v;
} else if ($k > 0) {
$myArray[$myKey] = $v;
$myKey = '';
}
}
EDIT: This answer is for:
$data ='KS/M/ 2013/1238 (220) 23/12/2013 (300)
(731) VALDETE BUZA ADEM JASHARI- PRIZREN, KS (526)
(591)
(740)
(540) DEINA (546)
(511) 3 Preparatet për zbardhim dhe substancat tjera për larje rrobash; preparatet për pastrim, shkëlqim, fërkim dhe gërryerje; sapunët; parfumet, vajrat esencialë, preparatet kozmetike, losionet për flokë, pasta për dhembe
14 Metalet e cmueshme dhe aliazhet e tyre; mallrat në metale të cmueshme ose të veshura me to, që nuk janë përfshire në klasat tjera; xhevahirët, gurët e cmueshëm; instrumentet horologjike dhe kronometrike (për matjen dhe regjistrimin e kohës)
25 Rrobat, këpucët, kapelat
35 Reklamim, menaxhim biznesi; administrim biznesi; funksione zyre';

Populating array with disk volume names on OSX - with spaces

Right now I'm using the command below to get the volume names of the mounted disks in OSX:
$exec = "df -lH | grep \"/Volumes/*\" | tr -s \" \" | sed 's/ /;/g'";
And parsing the output using this code:
$lines = explode("\n", $output);
$i = 0;
foreach ($lines as $line) {
$driveinfo = explode(";", $line);
$driveinfo[7] = trim($driveinfo[0]);
if (!empty($driveinfo[0]))
$allremovabledrives[$driveinfo[0]] = $driveinfo;
$i++;
}
This works fine if the Volume label doesn't have spaces in it:
[/dev/disk1s1] => Array
(
[0] => /dev/disk1s1
[1] => 32G
[2] => 31G
[3] => 674M
[4] => 98%
[5] => 0
[6] => 0
[7] => /dev/disk1s1
[8] => /Volumes/LUMIX
)
But if I mount a disk with a volume name that has spaces, disaster strikes and extra array values get added:
[/dev/disk4] => Array
(
[0] => /dev/disk4
[1] => 4.0T
[2] => 1.2T
[3] => 2.8T
[4] => 29%
[5] => 140741078
[6] => 347553584
[7] => /dev/disk4
[8] => /Volumes/My
[9] => Passport
[10] => Pro
)
Can anybody help me solve this problem? I'm not well versed in sed and command-line utilities ...
OK, the volume name is always the last field, and you know how many fields there are (9), so I would just split on whitespace and ask for that many fields. And not bother with any sed/awk/grep/tr stuff since you're already in a full-fledged programming system that can do what those commands do more efficiently within its own process space.
First, you can pass the list of volumes you want info about to df as arguments, which means you don't need the grep:
$df = shell_exec('df -lH /Volumes/*');
Now split on newline and get rid of the headers:
$rows = explode("\n", $df);
array_shift($rows);
Start building your result:
$result = array();
Here's where we don't need to use shell utilities just to make it possible to do with explode what we can already do with preg_split. The regular expression /\s+/ matches 1 or more whitespace characters in a row, so we don't get extra fields. The limit (9) means it only splits into 9 fields no matter how many more spaces there are - so the spaces in the last field (the volume name) get left alone.
foreach ($rows as $row) {
$cols = preg_split('/\s+/', $row, 9);
$result[$cols[0]] = $cols;
}
After all that, $result should look like you want.

split text by words and punctuation marks

I have this text:
A man’s jacket is of green color. He – the biggest star in modern history – rides bikes very fast (230 km per hour). How is it possible?! What kind of bike is he using? The semi-automatic gear of his bike, which is quite expensive, significantly helps to reach that speed. Some (or maybe many) claim that he is the fastest in the world! “I saw him ride the bike!” Mr. John Deer speaks. “The speed he sets is 133.78 kilometers per hour,” which sounds incredible; sounds deceiving.
I want to have the following resulting array:
words[1] = "A"
words[2] = "man's"
words[3] = "jacket"
...
words[n+1] = "color"
words[n+2] = "."
words[n+3] = "He"
words[n+4] = "-"
words[n+5] = "the"
...
This array should include all words and punctuation marks separately. Can that be performed using regexp? Can anyone help to compose it?
Thanks!
EDIT: based on request to show my work.
I'm processing the text using the following function, but I want to do the same in regex:
$text = explode(' ', $this->rawText);
$marks = Array('.', ',', ' ?', '!', ':', ';', '-', '--', '...');
for ($i = 0, $j = 0; $i < sizeof($text); $i++, $j++) {
$skip = false;
//check if the word contains punctuation mark
foreach ($marks as $value) {
$markPosition = strpos($text[$i], $value);
//if contains separate punctation mark from the word
if ($markPosition !== FALSE) {
//check position of punctation mark - if it's 0 then probably it's punctuation mark by itself like for example dash
if ($markPosition === 0) {
//add separate mark to array
$words[$j] = new Word($j, $text[$i], 2, $this->phpMorphy);
} else {
$words[$j] = new Word($j, substr($text[$i], 0, strlen($text[$i]) - 1), 0, $this->phpMorphy);
//add separate mark to array
$punctMark = substr($text[$i], -1);
$j += 1;
$words[$j] = new Word($j, $punctMark, 1, $this->phpMorphy);
}
$skip = true;
break;
}
}
if (!$skip) {
$words[$j] = new Word($j, $text[$i], 0, $this->phpMorphy);
}
}
The following will split on your specific text.
$words = preg_split('/(?<=\s)|(?<=\w)(?=[.,:;!?()-])|(?<=[.,!()?\x{201C}])(?=[^ ])/u', $text);
See working demo
Try making use of preg_split. Pass your punctuations(of your choice) inside the square brackets [ and ]
<?php
$str="A man’s jacket is of green color. He – the biggest star in modern history – rides bikes very fast (230 km per hour). How is it possible?! What kind of bike is he using? The semi-automatic gear of his bike, which is quite expensive, significantly helps to reach that speed. Some (or maybe many) claim that he is the fastest in the world! “I saw him ride the bike!” Mr. John Deer speaks. “The speed he sets is 133.78 kilometers per hour,” which sounds incredible; sounds deceiving.";
$keywords=preg_split("/[-,. ]/", $str);
print_r($keywords);
OUTPUT:
Array (
[0] => A
[1] => man’s
[2] => jacket
[3] => is
[4] => of
[5] => green
[6] => color
[7] =>
[8] => He
[9] => –
[10] => the
[11] => biggest
[12] => star
[13] => in
[14] => modern
[15] => history
[16] => –
Message truncated to prevent abuse of resources ... Shankar ;)

String parser/separation in PHP

I have data which I wish to be pasted into a textbox, it will be in the form E.G
Ryu Aiter D78:21:87:13 177 /177 1 / 6
Ryu Chronos D78:21:26:21 182 /182 0 / 6
Ryu Hermes D78:21:26:22 201 /201 0 / 6
Ryu Hefaistos D78:31:75:10 136 /136 1 / 2
Ryu Krotos D78:84:96:11 170 /170 1 / 6
Ryu Heros D78:65:51:31 175 /175 2 / 5
Ryu Arachnos D78:13:84:11 185 /185 0 / 5
its splits up like this
Base(max 16 chars)
Location(staring D , 12 chars)
econ/max econ (int/int)
used/Total(int/int)
What i wish to do is create a loop for each Row of text,
and then inside that loop chop out each part of the row into variables for each component.
as far as ideas on separating it i know that the : symbol is banned from names and bases.
so if i find the first ":" then step back 2 and take the next 12 chars that is my location
i know that can be done with a until loop and if(string[x]=':')
But how do i loops through rows?
And how can i separate the rest of the data in a row?
This is what regular expressions are for :P try this out:
$lines = explode( "\r\n", $data );
$users = array();
foreach( $lines as $line )
{
$matches = array();
$user = array();
preg_match( "/([^ ]+) ([^ ]+) ((?:[A-Z])(?:[0-9]+:){3}[0-9]+) ([0-9]+) \/([0-9]+) ([0-9]+) \/ ([0-9]+)/", $line, $matches );
list(,$user['name'],$user['base'],$user['location'],$user['econ'],$user['maxecon'],$user['used'],$user['total']) = $matches;
$users[] = $user;
}
You will have an array called users which contains a series of associative arrays with the components. Like below...
Array
(
[0] => Array
(
[total] => 6
[used] => 1
[maxecon] => 177
[econ] => 177
[location] => D78:21:87:13
[base] => Aiter
[name] => Ryu
)
[1] => Array
(
[total] => 6
[used] => 0
[maxecon] => 182
[econ] => 182
[location] => D78:21:26:21
[base] => Chronos
[name] => Ryu
)
etc, etc...
EDIT: I made a lot of assumptions about the data as you haven't given many details, if you need further help with the expression let me know.
UPDATE AS PER YOUR COMMENT:
Line 182: $name = htmlspecialchars(mysql_real_escape_string($_POST['name']));
Line 188: $tecon = htmlspecialchars(mysql_real_escape_string($user['econ']));
You should turn on display_errors as they were simple syntax errors that could easily be debugged.
Can you just use explode and gradually break it down?
eg.
explode the entry into seperate lines at '\n'
then explode each line into 2, everything before the 1st ':', and everything after
explode the 1st part into pieces using each 'space' to give you Name, Base, Location
explode the 2nd part using 'space', ':' or '/' to give you econ/max econ and used/Total
if(preg_match_all('/^([a-z]{1,16})\s+([a-z]{1,16})\s+(D\d+):(\d+):(\d+):(\d+)\s+(\d+)\s+\/(\d+)\s+(\d+)\s+\/\s+(\d+)$/mi', $yourinputgoeshere, $match) {
print_r($match);
}
This should, untested, get everything into a large array, separated. Untested
Extending the same idea i am trying to use preg match for a single line on another page.
i use the code
$data = $_POST['list'];
$matches = array();
$user = array();
preg_match( "/(.+?) ((?:[A-Z])(?:[0-9]+:){3}[0-9]+) ([0-9]+) \/([0-9]+) ([0-9]+) \/ ([0-9]+)/", $data, $matches );
list(,$user['base'],$user['location'],$user['econ'],$user['maxecon'],$user['used'],$user['total']) = $matches;
$base = $users['base'];
$location = $users['location'];
$tecon = $users['econ'];
i used echo to print out £data and it contains the data as expected but the same code without the lines loop does not seperate the parts of my data into the array..in fact the array size of $user remains empty, what has gone wroung?

Categories