I'm working in a company where I have this project to create a web application based on the products my company is making.
There is an inside server which contains all the data from my company. What I have to do is parse the data the oracle server is retrieving. It is retrieving .lst files which can be easily translated to .csv using Excel or some php packages.
I successfully imported the Clients table into my MySQL database using the LOAD DATA INFILE command. But I'm running some issues when I want to parse the Articles table.
The columns/values aren't necessarily separated by semi-colons. To parse the data I'll have to say for example :
The first 6 characters are the Article ID
The next 35 characters are the description of the article
and so on...
Is there a way I could achieve this when using the LOAD DATA INFILE command, or should I format the file correctly using PHP then use this command and if so what could be the best approach?
Thanks guys, I hope I made myself clear since english isn't my primary language. :P
Edit : those are rows.
51016 51016 BOITE ORANGINA 33cls CASHS "24" 040430024000330 0000000000 1 01000000550009000 000000NNNNNN caisse 0000003750000000000001230
51019 51019 BOITE OASIS ORANGE CASHS "24" 33cl 040430024000330 0000000000 1 01000000550009000 000000NNNNNN caisse 0000003670000000000001230
The first line is getting parsed correctly while the second isnt.The double quote after 24 is being put into the next column. I just wanted to know if it was possible to do something about it, like deleting the double quotes.
A previous developer created an application to manage the articles, clients from the company. Unfortunately he cannot help me anymore but here is a ligne that describe a row.
import_a;Code_article;6;designation;35;designation2;35;Code_famille;2;Code_sousfamille;4;unite_condition;3;contenance;6/1000;Champ_vide;2;degre;4/10;champ_vide_6;6;Code_emballage;4;Champ_vide2;8;validite;1;Champ_vide3;7;code_tva;2;taux_tva;9/100;poids;6/1000;champ_vide4;19;montant_droits;6/1000;valide;1;rupture;1;edit_tarif;1;pre_commande;1;gratuit_autorise;1;trans_port;1;Champ_libre;1;caisse;15;prix_revient;9/100;stock;6/1;Champ_vide5;5;code_fournisseur;11/1
import_a => It's the filename you can just ignore that.
Then you have the name of the column followed by the number of characters. For example Code_articles is composed of 6 characters and so on.
You can also just ignore the duplicate ID Key at the beginning. But in total there should be 31 columns.
You can use this perl script to start your testing. The most important thing is the adjust the $def line according to your real data, until your get the correct result.
#!/usr/bin/perl
$input_file = "/tmp/a.lst";
$output_file = "/tmp/a.csv";
$testing = 1; #testing, print out directly first 100 lines
# we are using tab (#9) for the output csv file
$delim ="\t";
# output column header
$output_header = 1;
$defs= "import_a;Code_article;6;Code_article2;6;designation;29;designation2;35;Code_famille;2;Code_sousfamille;4;unite_condition;3;contenance;6/1000;Champ_vide;2;degre;4/10;champ_vide_6;6;Code_emballage;4;Champ_vide2;8;validite;1;Champ_vide3;7;code_tva;2;taux_tva;9/100;poids;6/1000;champ_vide4;19;montant_droits;6/1000;valide;1;rupture;1;edit_tarif;1;pre_commande;1;gratuit_autorise;1;trans_port;1;Champ_libre;1;caisse;15;prix_revient;9/100;stock;6/1;Champ_vide5;5;code_fournisseur;11/1";
my #input_fields, #input_fieldwidths, #input_fieldwidth_max, $input_field_no =0;
#defs= split(";",$defs);
$total_defs=$#defs;
$total_cols = 0;
$total_width = 0;
for($x=0; $x<$total_defs /2; $x++)
{
push(#input_fields, $defs[$x*2+1]);
$width = $defs[$x*2+2];
if($width=~/(.*)\/(.*)/){
$mw= $1;
$xw= $2;
}
else{
$mw = $width;
$xw= 0;
}
$total_width += $mw;
push(#input_field_widths,$mw);
push(#input_field_widths_max, $xw);
$total_cols ++;
}
if($testing){
for($x=1; $x<$total_cols; $x++)
{
print "$input_fields[$x]: $input_field_widths[$x]\n";
}
}
open(INPUT, $input_file) || die "Can not open input file";
open(OUTPUT, ">$output_file" ) || die "Can not open output file";
# this is the csv head
if($output_header){
print OUTPUT "$input_fields[0]";
for($x=1; $x<$total_cols; $x++)
{
print OUTPUT "\t$input_fields[$x]";
}
print OUTPUT "\n";
}
$lines=0;
foreach $l (<INPUT>)
{
chop($l);
$pos =0;
for($f=0; $f < $total_cols; $f++)
{
$val = substr($l, $pos, $input_field_widths[$f]);
print OUTPUT $delim if($pos);
print $delim if($pos && $testing);
print OUTPUT $val;
print $val if($testing);
$pos += $input_field_widths[$f];
}
print OUTPUT "\n";
print "\n" if($testing);
$lines++;
if($testing && $lines>100) { last;};
}
print $lines , " lines transformed\n";
close(INPUT);
close(OUTPUT);
Edit: for a comma separated quoted csv format:
#!/usr/bin/perl
$input_file = "/tmp/a.lst";
$output_file = "/tmp/a.csv";
# we are using tab (#9) for the output csv file
$delim =";";
$testing = 1; #testing, print out directly first 10 lines
$quote ="'";
# output column header
$output_header = 1;
$defs= "import_a;Code_article;6;Code_article2;6;designation;29;designation2;35;Code_famille;2;Code_sousfamille;4;unite_condition;3;contenance;6/1000;Champ_vide;2;degre;4/10;champ_vide_6;6;Code_emballage;4;Champ_vide2;8;validite;1;Champ_vide3;7;code_tva;2;taux_tva;9/100;poids;6/1000;champ_vide4;19;montant_droits;6/1000;valide;1;rupture;1;edit_tarif;1;pre_commande;1;gratuit_autorise;1;trans_port;1;Champ_libre;1;caisse;15;prix_revient;9/100;stock;6/1;Champ_vide5;5;code_fournisseur;11/1";
my #input_fields, #input_fieldwidths, #input_fieldwidth_max, $input_field_no =0;
#defs= split(";",$defs);
$total_defs=$#defs;
$total_cols = 0;
$total_width = 0;
for($x=0; $x<$total_defs /2; $x++)
{
push(#input_fields, $defs[$x*2+1]);
$width = $defs[$x*2+2];
if($width=~/(.*)\/(.*)/){
$mw= $1;
$xw= $2;
}
else{
$mw = $width;
$xw= 0;
}
$total_width += $mw;
push(#input_field_widths,$mw);
push(#input_field_widths_max, $xw);
$total_cols ++;
}
if($testing){
for($x=0; $x<$total_cols; $x++)
{
print "$input_fields[$x]: $input_field_widths[$x]\n";
}
}
open(INPUT, $input_file) || die "Can not open input file";
open(OUTPUT, ">$output_file" ) || die "Can not open output file";
# this is the csv head
if($output_header){
print OUTPUT "$input_fields[0]";
for($x=1; $x<$total_cols; $x++)
{
print OUTPUT "\t$input_fields[$x]";
}
print OUTPUT "\n";
}
$lines=0;
foreach $l (<INPUT>)
{
chop($l);
$pos =0;
for($f=0; $f < $total_cols; $f++)
{
$val = substr($l, $pos, $input_field_widths[$f]);
print OUTPUT $delim if($pos);
#print $delim if($pos && $testing);
print OUTPUT $quote, $val, $quote;
if($testing){
print $input_fields[$f] , "=", $val, "\n";
}
$pos += $input_field_widths[$f];
}
print OUTPUT "\n";
print "\n" if($testing);
$lines++;
if($testing && $lines>0) { last;};
}
print $lines , " lines transformed\n";
close(INPUT);
close(OUTPUT);
Related
I've written some code to read in data from a text file.
The data looks like this:
11:12:12:test titel 1
12:13:13:test titel 2
13:14:14:test titel 3
the following code reads the date, splits it one string for each line, those go in one array. This works perfectly.
After this, it should devide each line again in string that go in an array, and all these arrays go into one multidimensional array.
This last part doesnt work...
I think it's strange that instead of errors, of half the page, it shows just an empty page...
also, I've tried putting some of the code in comment, and so I've narrowed it down a bit. I give you guys the commented code, but all the comments should go away, and it should work like that!
thanks!
<?php
$filename = "data.txt";
$fp = fopen($filename, "r");
$content = fread($fp, filesize($filename));
$lines = explode("\n", $content);
$parts = null;
fclose($fp);
print_r($lines);
echo sizeof($lines);
for ($i=0; $i < sizeof($lines)-1 ; $i++) { //the minus 1 corrects the empty line automatically added when saving the data.txt file
//$tempParts[] = explode(":", $lines[i]);
//array_push($parts, $tempParts);
}
//echo "<br/>"
echo "all parts: "
//for ($row=0; $row < sizeof($lines)-1; $row++) {
// for ($col=0; $col < sizeof($parts[$row]); $col++) {
//echo $parts[$row][$col];
// }
//}
?>
I think preg_split will do what you want.
$filename = "data.txt";
$fp = fopen($filename, "r");
$content = fread($fp, filesize($filename));
//$content = "11:12:12:test titel 1
12:13:13:test titel 2
13:14:14:test titel 3";
$arr = preg_split("/(:|\n)/" ,$content);
var_dump($arr);
See here: http://www.phpliveregex.com/p/hNH
Click on preg_split on the right side of the screen to make it work
Maybe this works better for you?
preg_match_all("/(\d+):(\d+):(\d+):(.*)/", $content, $arr);
Click preg_match_all:
http://www.phpliveregex.com/p/hNW
I'm not sure to understand exactly what you want but you can try this :
if (!$fp = fopen("data.txt","r")) {
die("fail to open");
}else {
$all = array();
$row = 1;
while(!feof($fp)) { // foreach line
$ligne = fgets($fp,255); // get line content
$cols = explode(':', $line); // gets cols
$all[$row++] = $cols; // put cols on current row
}
var_dump($all); // dump all data stored by row
fclose($fp);
}
Question: A string is said to be complete if it contains all the characters from a to z. Given a string, check if it complete or not.
Input
First line of the input contains the number of strings N. It is followed by N lines each contains a single string.
Output
For each test case print "YES" if the string is complete, else print "NO"
Constraints
1 <= N <= 10
The length of the string is at max 100 and the string contains only the characters a to z
YOU CAN CHECK HERE http://www.hackerearth.com/problem/algorithm/complete-string-4/
When i submit the PHP code , it shows the result is wrong
<?php
$allowedString = array('random','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
function execute($fileName = "3\nwyyga\nqwertyuioplkjhgfdsazxcvbnm\nejuxggfsts"){
global $allowedString;
//$handle = fopen($fileName, 'r');
$l=0;
$text = array();
$text = explode("\n", $fileName);
$z=0;
// print_r($text);
if ($text[0]>=1 && $text[0]<=10){
for($i=1;$i<=$text[0];$i++){
if(strlen($text[$i])>=26 && strlen($text[$i])<=100 ){
$count = 0;
for($z=1;$z<27;$z++){
$pos = strpos($text[$i], $allowedString[$z]);
if($pos === false){
continue;
}else{
$count++;
}
}
if($count == 26){
echo 'YES'."<br>";
}else{
echo 'NO'."<br>";
}
}else{
echo 'NO'."<br>";
}
}
}
}
execute();
?>
After a quick look at the page, it seems that the site is STDIO (Standard Input/Output) for input and output data rather than files. So, you shouldn't read/write data to a file.
Here is some code:
<?php
//This will input a file from Standard Input
$line = trim(fgets(STDIN));
//This will output the string to Standard Output
fwrite(STDOUT, $output);
?>
I have a file which has only one line, with a number from 1 to 40, and I have the following code:
$file_line = file('../countersaver.txt');
foreach ($file_line as $line) {
$line_result = $line;
}
echo $line;
I have to calculate the result of $line - 1 and echo that result.
But when i do:
$line = $line - 1;
Then it shows $line - 1 and doesn't actually do the calculation.
Your code is weak to changes of the file contents. If someone adds a few blank lines, for example, your code won't work. Try this out instead:
$number = trim(file_get_contents('../countersaver.txt'));
echo $number - 1;
Try replacing
$line = $line - 1;
echo $line
with
$line = ($line -1);
echo $line
This will print 19 instead of 20-1.
I don't see an approved answer here but for anyone looking at this post, if you have a variable that you want PHP to read as a number you can use intval() function. Details covered here...
http://php.net/manual/en/function.intval.php
Try this:
$fin = #fopen("path to file", "r");
if ($fin) {
while (!feof($fin)) {
$buffer = fgets($fin);
}
fclose($fin);
}
I have a string variable which contains some text (shown below). The text has line breaks in it as shown. I would like to search the text for a given string, and return the number of matches per line number. For instance, searching for "keyword" would return 1 match on line 3 and 2 matches on line 5.
I have tried using strstr(). It does a good job finding the first match, and giving me the remaining text, so I can do it again and again until there are no matches. Problem is I do not know how to determine which line number the match occurred on.
Hello,
This is some text.
And a keyword.
Some more text.
Another keyword! And another keyword.
Goodby.
Why not split the text on line-feeds and loop, use the index + 1 as a line number:
$txtParts = explode("\n",$txt);
for ($i=0, $length = count($txtParts);$i<$length;$i++)
{
$tmp = strstr($txtParts[$i],'keyword');
if ($tmp)
{
echo 'Line '.($i +1).': '.$tmp;
}
}
Tested, and working. Just a quick tip, since you're looking for matches in a text (sentences, upper- and lower-case etc...) perhaps stristr (case-insensitive) would be better?An example with foreach and stristr:
$txtParts = explode("\n",$txt);
foreach ($txtParts as $number => $line)
{
$tmp = stristr($line,'keyword');
if ($tmp)
{
echo 'Line '.($number + 1).': '.$tmp;
}
}
With this code you can have all data in one array (Linenumber and position numbers)
<?php
$string = "Hello,
This is some text.
And a keyword.
Some more text.
Another keyword! And another keyword.
Goodby.";
$expl = explode("\n", $string);
$linenumber = 1; // first linenumber
$allpos = array();
foreach ($expl as $str) {
$i = 0;
$toFind = "keyword";
$start = 0;
while($pos = strpos($str, $toFind, $start)) {
//echo $toFind. " " . $pos;
$start = $pos+1;
$allpos[$linenumber][$i] = $pos;
$i++;
}
$linenumber++; // linenumber goes one up
}
foreach ($allpos as $linenumber => $position) {
echo "Linenumber: " . $linenumber . "<br/>";
foreach ($position as $pos) {
echo "On position: " .$pos . "<br/>";
}
echo "<br/>";
}
Angelo's answer definitely provides more functionality and is probably the best answer, but the following is simple and seems to work. I will continue to play with all solutions.
function findMatches($text,$phrase)
{
$list=array();
$lines=explode("\n", $text);
foreach($lines AS $line_number=>$line)
{
str_replace($phrase,$phrase,$line,$count);
if($count)
{
$list[]='Found '.$count.' match(s) on line '.($line_number+1);
}
}
return $list;
}
I'm trying to parse the resources contained in a resources.arsc file as discussed in this question. I know the androidmanifest.xml file identifies resources located in the .arsc file. I have successfully managed to parse the header of the .arsc file, I can't figure out how to parse the resources themselves.
Can somebody please help me figure out how to parse the resources contained in an .arsc file?
My parsing code so far:
<?php
$doc = fopen('resources.arsc', 'r+');
for($i=1;$i<10;$i++){
$res[$i] = _unpack('V', fread($doc, 4));
}
for ($i = 0, $j = $res[6]; $i <= $j; $i++) {
$word = fread($doc, 4);
$stroffs[] = _unpack('V', $word);
}
$strings = array();
$curroffs = 0;
foreach($stroffs as $offs){
//read length
$len = _unpack('v', fread($doc, 2));
//read string
if($len>0){
$str = fread($doc, $len*2);
}else{
$str = '';
}
//null
$wd = fread($doc, 2);
//utf-16le
$strings[] = mb_convert_encoding($str, 'gbk', 'UTF-16LE');
//curr offset
$curroffs += ($len+1)*2 + 2;
}
$tpos = ftell($doc);
read_doc_past_sentinel($doc);
//fseek($doc, $tpos + $tpos % 4);
$i = 0;
$xmls = $strings;
print_r($xmls);
//------------------------------------
//and then...somebody konw format or continue parse?
//------------------------------------
function read_doc_past_sentinel(&$doc){
$pos = ftell($doc);
$count= 0;
while($word = fread($doc, 4)){
if(_unpack('V', $word)==-1)break;
}
$n = 1;
if ($count < $n){
while($word = peek_doc($doc, 4)){
if(_unpack('V', $word) != -1)break;
fread($doc, 4);
$n++;
if(isset($count) && $count >= $n)break;
}
echo 'skip '.$n.' chars<br />';
}
}
function peek_doc(&$doc, $size){
$data = fread($doc, $size);
fseek($doc, ftell($doc)-$size);
return $data;
}
function _unpack($m, $b){
//if(!$b)return '';
$res = unpack($m, $b);
return $res[1];
}
?>
This is a fairly complicated binary file. You will need way more code than that to parse it. :)
My suggestion would be to use the same code that the platform does -- that is the ResTable and related classes found here:
frameworks/base/include/utils/ResourceTypes.h
frameworks/base/libs/utils/ResourceTypes.cpp
Note that ResourceTypes.h also has definitions for the complete structure of the resource table (which the classes there use to parse it).
You may also just be able to use the aapt tool. This has a number of options for parsing resource-related data out of an .apk:
aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
badging Print the label and icon for the app declared in APK.
permissions Print the permissions from the APK.
resources Print the resource table from the APK.
configurations Print the configurations in the APK.
xmltree Print the compiled xmls in the given assets.
xmlstrings Print the strings of the given compiled xml assets.
If there is some other data you want not available with those commands, consider modifying the tool code in frameworks/base/tools/aapt to add stuff to parse out what you want. This tool is using ResTable to parse the resources.