Вот так (потому что я сказал это в комментариях)
$str = 'Invoice No..... Sale Type Desc...... Misc Amt.... Misc Acc.. Misc Acc Desc.....................................';
$f = fopen('php://temp', 'w+');
fwrite($f, $str);
rewind($f);
$headers = [];
$header = '';
while(false !== ($c = fgetc($f))){
if($c != '.'){
$header .= $c;
}elseif(!empty($header)){
$headers[] = trim($header);
$header = '';
}
}
print_r($headers);
Выходы
Array
(
[0] => Invoice No
[1] => Sale Type Desc
[2] => Misc Amt
[3] => Misc Acc
[4] => Misc Acc Desc
)
Заметьте, я сделал это без использования смещения, но я упомянул об этом в комментариях, и мне нравится делать странные вещи, подобные этой. Это приятно.
Конечно, вы можете сделать это для того же результата:
$str = 'Invoice No..... Sale Type Desc...... Misc Amt.... Misc Acc.. Misc Acc Desc.....................................';
print_r(array_filter(array_map('trim',explode('.', $str))));
Но это далеко-далеко не просто.
Песочница
И если вам не нравится, что все ключи странные, вы можете просто добавить массив_значений на эту присоску.
print_r(array_values(array_filter(array_map('trim',explode('.', $str)))));
LOL, еще один понедельник.
UPDATE
Вы также можете использовать файл-конвертер потока для исправления файла для чтения в формате CSV. В PHP5.4 (я думаю или 5.3) SplFileObj отсутствует fgetcsv
, и я использовал трюк с ними для исправления этого класса ....:)
Это была моя точка зрения (но я многого не знаю)
$str = 'Invoice No..... Sale Type Desc...... Misc Amt.... Misc Acc.. Misc Acc Desc.....................................
somedata .... someother stuff ... foobar ... hello ... world..
';
//pretend this is a real file
$f = fopen('php://temp', 'w+');
fwrite($f, $str);
rewind($f);
$headers = [];
$num_headers = 0;
$i = 1;
while(false !== ($c = fgetcsv($f))){
//if there is only one element assume the delimiter is wrong
if(count($c) == 1){
//you could test the string for multiple delimiters and change
/*
if(strpos($c, '.')){
$regex = '/\.+/'
}else if(strpos($c, '~')){
$regex = '/~+/'
} etc....
*/
//use memory buffer to fix files with .'s but still read them as
//a normal CSV file, php://memory is really fast.
//and this gives us all the parsing benefits of fgetcsv
//you could use any delimiter here you want.
$fixed = trim(preg_replace('/\.+/', ',', $c[0]),',');
$m = fopen('php://memory', 'w+');
fwrite($m, $fixed);
rewind($m);
$c = fgetcsv($m);
}
//trim any spaces, not a bad idea anyway
$c = array_map('trim', $c);
//if no headers use the first line of file as the header
if(empty($headers)){
$headers = $c;
//count them (see below)
$num_headers = count($headers);
continue;
}
//array_combine is a good choice for header => values
//but the arrays have to be the same size
if(count($c) != $num_headers) die("missing dilimter on line {$i}");
$line = array_combine($headers, $c);
//continue with normal csv opperation
print_r($line);
++$i; //track the line number
}
Выход
Array
(
[Invoice No] => somedata
[Sale Type Desc] => someother stuff
[Misc Amt] => foobar
[Misc Acc] => hello
[Misc Acc Desc] => world
)
UPDATE
Как я уже упоминал в комментариях (после выяснения, что это был HTML). Вы можете использовать DOM-парсер. Одна из них, которую я использовал в прошлом, это PHPQuery
, она немного устарела. Но это приятно, потому что вы можете использовать синтаксис jQuery. Например, скажем, у вас есть
<ul id="title" >
<li>header</li>
<li>header</li>
<li>header</li>
</ul>
Вы можете найти это с чем-то вроде этого (это было давно, так что если это не так, извините)
$length = $PHPQuery->find("#headers li")->lenght;
for($i=0;$i<$lenght;++$i){
echo $PHPQuery->find("#headers li:eq($i)")->text();
}
Вы можете даже получить атрибуты, используя, например, ->attr('href')
. По сути, вы можете воспользоваться преимуществами структуры HTML и извлечь то, что вам нужно, вместо того, чтобы конвертировать ее в текст и пытаться удалить кучу «вещей»
Ура!