How to Parse Fixed Width Column Text in PHP

How to parse fixed width column text in php?

You can preg_split by space

$words = preg_split("/[\s]+/", $input);

//if your lines seperated by `\n` new line you could:
$inputArr = preg_split("/\R+/", $input);
foreach($inputArr as $value) {
$out = preg_split("/\s+/", $value);
var_dump($out);
}

Thanks

How to parse a fixed width text file in PHP?

You can try

$file = "log.txt";
$list = $part = array();

foreach ( file($file) as $line ) {
$line = trim($line);
if (strpos($line, "|") === false) {
continue;
}
$line = explode("|", $line) and $line = end($line);
$list[] = substr($line, 0, 3) . " " . substr($line, 3);
}
var_dump($list);

Output

array
0 => string '192 ' (length=4)
1 => string 'SAT CLIMO' (length=10)
2 => string ' 67 999999' (length=10)
3 => string ' 70 ' (length=4)
4 => string ' 66 ' (length=4)
5 => string ' 7 ' (length=4)
6 => string ' 32 999999' (length=10)
7 => string ' 999' (length=10)
8 => string ' ' (length=1)
9 => string ' ' (length=1)
10 => string '192 ' (length=4)
11 => string 'SAT CLIMO' (length=10)
12 => string '999 999999' (length=10)
13 => string '999 ' (length=4)

Parse a text file into 4 columns, with the 3rd column sometimes has value and sometimes not (PHP)

Your problem is solvable by a regular-expression. but it is a little bit tricky. here is my abbroach. It don't care how much spaces are between the columns. it matches for specific patterns of the columns to distinct them.

// reduced test-data for simplicity
$data = ' 246/RD/2010 05.01.2010 211/P 12.11.2010
247/RD/2010 05.01.2010 195/P 09.11.2010
248/RD/2010 05.01.2010 13.10.2010
251/RD/2010 05.01.2010 274/P 08.12.2010';

// regular-expression with groups to get your needed columns
$re = '/^\s*([0-9]+\s*[0-9A-Z\/]+)\s+([0-9]{2}\.[0-9]{2}\.[0-9]{4})\s+([0-9]{2}\.[0-9]{2}\.[0-9]{4})*(\s*$|([0-9A-Z\/]+\s*[0-9]{2}\.[0-9]{2}\.[0-9]{4}$))/m';

// match it
preg_match_all ($re, $data, $matches, PREG_SET_ORDER, 0);

// $matches is now an multidimensional array with an array for every line.
// those line-arrays will contain columns 1 to 5 where 3 will
// be your third column (sometimes empty) and 5 will be the last column.

// [
// ['246/RD/2010', '05.01.2010', '', '', '211/P 12.11.2010'],
// ['247/RD/2010', '05.01.2010', '', '', '195/P 09.11.2010'],
// ['248/RD/201', '05.01.2010', '13.10.2010', '', ''],
// ['251/RD/2010', '05.01.2010', '', '', '274/P 08.12.2010'],
// ]

How to write fixed width text file with PHP

Take a look at the str_pad method. E.g.

str_pad('Somevalue', 20, " ", STR_PAD_LEFT); 

Will left-pad the string "Somevalue" with spaces, giving

"           Somevalue"

Whereas

str_pad('Somevalue', 20);

Will right-pad the string with spaces, giving:

 "Somevalue           "

Is it possible to parse a fixed width file without knowing the width of each column or the column names and converting it to a CSV?

No !!!

It is only very simplest Fixed width files could be passed in this way.
Fixed width files can

  • Have multiple record layouts
  • Binary fields
  • Could be Cobol files
  • For some fields you need to know what the field definition is to correctly
    interpret them. For example decimal points could be assumed i.e. 12345 could be 123.45,
    1.2345 etc.
  • Text fields are normally left justified,

For fixed width files you need a file Description (chema)

Cobol File

A common source of Fixed width files is from Cobol applications.
Cobol Fixed width files

  • Never have Column headings
  • Generally no space between fields
  • Could have binary fields
  • Decimal points are assumed
  • Zoned Decimal

Have a look at the file in this questions

  • Is this possible to convert EBCDIC Comp-3 file to ASCII file values using java?

Software

  • Microsoft Excel / Access + most spreadsheets has Fixed width import wizards
  • RecordEditor/Recsveditor have wizards for fixed width files + can edit fixed width files

How to write fixed width text file with PHP and MYSQL data

First you decide a static width for your first column, say 100 characters.

Then try with this code

$myFile = "testFile.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
$stringData = " ".$cust2[Ac_desc];
$spaces = 100 - strlen($cust2[Ac_desc]); // get the number of spaces to add
fwrite($fh, $stringData);
$stringData = str_repeat(" ",$spaces).$cust2[Add1]."\n";
fwrite($fh, $stringData);
fclose($fh);

Parse fixed-width files

As user604939 mentions, unpack is the tool to use for fixed width fields. However, unpack needs to be passed a template to work with. Since you say your fields can change width, the solution is to build this template from the first line of your file:

my @template = map {'A'.length}        # convert each to 'A##'
<DATA> =~ /(\S+\s*)/g; # split first line into segments
$template[-1] = 'A*'; # set the last segment to be slurpy

my $template = "@template";
print "template: $template\n";

my @data;
while (<DATA>) {
push @data, [unpack $template, $_]
}

use Data::Dumper;

print Dumper \@data;

__DATA__
<c> <c> <c>
Dave Thomas 123 Main
Dan Anderson 456 Center
Wilma Rainbow 789 Street

which prints:


template: A8 A10 A*
$VAR1 = [
[
'Dave',
'Thomas',
'123 Main'
],
[
'Dan',
'Anderson',
'456 Center'
],
[
'Wilma',
'Rainbow',
'789 Street'
]
];


Related Topics



Leave a reply



Submit