Дано: Форма с полем типа textarea, в которое методом копипаста (Ctrl-C Ctrl-V) вставляется содержимое таблице Excell.
Нужно, превратить эти данные в двухмерный массив типа $arr[номер_строки][номер_ячейки].
Собственно, делалось это вот так. Т.е. дробим полученную строку по символам перевода каретки (\n), а то что раздробилось — дробим по символу табуляции (\t) и получаем массив $arr.
function tableToArray($textarea) {
$arrtr = explode("\n", $textarea);
foreach ($arrtr as $k => $v) {
$arr[$k] = explode("\t", $v);
}
return $arr;
}
Ничто не предвещало беды, но, вмешался человеческий фактор. Кое-кто повадился ставить символы перевода каретки прямо в ячейках таблицы, и всё пошло по… лесу.
Пришлось усложнить алгоритм.
function tableToArray($textarea) {
//Делаем проверку первой строки. По ней считаем количество колонок в таблице
$prearrtr = explode("\n", $textarea);
$tdcount = count(explode("\t", $prearrtr[0])) - 1; //Получаем номер последней ячейки для каждой строки
$tabattr = explode("\t", $textarea); //Дробим данные по символу табуляции
$forbiddenCharacters = "\/*?<>|+%!\n\r"; //Запрещённые символы
$arr = [];
$trnum = 0;
$tdnum = 0;
foreach ($tabattr as $v) {
if ($tdnum < $tdcount) {
//Если у нас не последняя ячейка
$arr[$trnum][$tdnum] = preg_replace("/[${forbiddenCharacters}]/", '', $v);
$tdnum++;
}else{
//Если ячейка последняя, то она содержит и первую ячейку следующей строки
//Кроме того, и в первой и в последней ячейке могут быть ненужные переводы строк
//Поэтому, бьём на массив, удаляем пустые ячейки, перенумеровываем.
$finalv = array_values(array_diff(explode("\n", $v), array('')));
//Пишем последнюю ячейку
$arr[$trnum][$tdnum] = preg_replace("/[${forbiddenCharacters}]/", '', $finalv[0]);
$trnum++;
$tdnum = 0;
$arr[$trnum][$tdnum] = preg_replace("/[${forbiddenCharacters}]/", '', $finalv[1]);
$tdnum++;
}
}
return $arr;
}
Если смотреть в код, то в принципе алгоритм понятен. Есть пара моментов, которые поясню отдельно.
Первая строка таблицы (шапка) — эталонная и её никто не правит. Поэтому, в ней нет символов переходов строк. По ней считаем количество столбцов в таблице.
Дробим данные по табуляции и закидываем в массив $tabattr. Проблема в том, что последняя ячейка текущей строки сливается с первой ячейкой следующей и попадает в одну ячейку массива. Поэтому, дойдя до последней ячейки (по номеру $tdcount), я дроблю полученные данные по символу перевода каретки и получаю массив $finalv. Удаляю из $finalv пустые ячейки и перенумеровываю ключи.
Теперь, первую ячейку $finalv[0] загоняю в последнюю ячейку текущей строки массива таблицы, а вторую ячейку $finalv[1] закидываю в первую ячейку следующей строки.
Собственно, на этом пока всё.