Intereting Posts
PHP: нужен ли gettext LC_MESSAGES? Оператор PHP Mysqli возвращает одну строку, пострадали -1 строки, и не было ошибок Как создать функцию в PHP, которая сортирует массив на основе одного из его ключей Мобильный переадресация с использованием htaccess Как включить –enable-soap в php на linux? Как json_encode php массив, но ключи без кавычек PHP Объекты сломаны, $ это неопределено Соотношения уровня сервиса и модели с поддержкой домена php / SQL – печатает много слов 4 раза между каждыми 4 именами со многими условиями Как отправить несколько значений полей ввода с использованием метода ajax post как получить контент с внешней веб-страницы по php? Не удается получить доступ к веб-приложениям apache локально с использованием имени IP или ПК Получить относительную дату из функции NOW () Как использовать wget в php? Что такое хороший алгоритм или библиотека для обрезки изображений, чтобы избежать пробелов или пустых областей?

HTML-таблица для массива PHP

У меня есть школьный календарь онлайн, но я хочу иметь его в своем приложении. К сожалению, я не могу заставить его работать с PHP и регулярным выражением.

Проблема в том, что ячейки таблицы не разделены поровну и что они изменяются для каждого класса. Вы можете найти расписание здесь и здесь .

Регулярное выражение, которое я пробовал, следующее:

<td rowspan='(?:[0-9]{1,3})' class='value'>(.+?)<br/>(.+?)<br/>(.+?)<br/><br/><br/></td> 

Но это работает неправильно!

Конечный массив должен выглядеть примерно так:

 [0] => Array ( [0] => maandag //the day [1] => 1 //lesson period [2] => MEN, 16, dm //content of the cell ) 

Я надеюсь, что этот вопрос достаточно ясен, потому что я не английский;)

Solutions Collecting From Web of "HTML-таблица для массива PHP"

Удачи вам в этом, это будет сложно … просто «использование парсера HTML» на самом деле не позволит избежать основной проблемы, которая является характером таблицы, в которой используются ряды строк. Несмотря на то, что всегда полезно использовать HTML-парсер для синтаксического анализа больших объемов HTML, если вы можете разбить этот HTML на более мелкие надежные куски, тогда анализ с использованием других методов всегда будет более оптимальным (но, очевидно, более подверженным тонкие неожиданные различия в HTML) .

Нормализовать таблицу

Если бы это был я, я бы начал с чего-то, что может обнаружить, где начинается и заканчивается ваша таблица (поскольку я бы не хотел анализировать всю страницу даже при использовании HTML Parser, если мне это не нужно) :

 $table = $start = $end = false; /// 'Vrijdag' should be unique enough, but will fail if it appears elsewhere $pos = strpos($html, 'Vrijdag'); /// find your start and end based on reliable tags if ( $pos !== false ) { $start = stripos($html, '<tr>', $pos); if ( $start !== false ) { $end = stripos($html, '</table>', $start); } } if ( $start !== false && $end !== false ) { /// we can now grab our table $html; $table = substr($html, $start, $end - $start); } 

Затем из-за случайного пути ячейки натянуты вертикально (но кажутся однородными по горизонтали), я бы выбрал колонку «день» и работал вниз.

 if ( $table ) { /// break apart based on rows $rows = preg_split('#</tr>#i', $table); /// foreach ( $rows as $key => $row ) { $rows[$key] = preg_split('#</td>#i', $row); } } 

Вышеупомянутое должно дать вам что-то вроде:

 array ( '0' => array ( '0' => "<td class='heading'>1", '1' => "<td rowspan='1' class='empty'>" '2' => "<td rowspan='5' class='value'>3D<br/>009<br/>Hk<br/><br/><br/>" ... ), '0' => array ( '0' => "<td class='heading'>2", '1' => "<td rowspan='2' class='empty'>" '2' => "<td rowspan='3' class='value'>Hk<br/>" ... ), ) 

Теперь, когда у вас есть это, вы можете сканировать по каждой строке и где preg_match rowspan, вам нужно будет создать копию информации этой ячейки в строке ниже (в нужном месте), чтобы фактически создать полную таблицу Структура (без строк) .

 /// can't use foreach here because we want to modify the array within the loop $lof = count($rows); for ( $rkey=0; $rkey<$lof; $rkey++ ) { /// pull out the row $row = $rows[$rkey]; foreach ( $row as $ckey => $cell ) { if ( preg_match('/ rowspan=.([0-9]+)./', $cell, $regs) ) { $rowspan = (int) $regs[1]; if ( $rowspan > 1 ) { /// there was a gotcha here, I realised afterwards i was constructing /// a replacement pattern that looked like this '$14$2'. Which meant /// the system tried to find a group at offset 14. To get around this /// problem, PHP allows the group reference numbers to be wraped with {}. /// so we now get the value of '$1' and '$2' inserted around a literal number $newcell = preg_replace('/( rowspan=.)[0-9]+(.)/', '${1}'.($rowspan-1).'${2}', $cell); array_splice( $rows[$rkey+1], $ckey, $newcell ); } } } } 

Вышеизложенное должно нормализовать таблицу, так что ряды столбцов больше не являются проблемой.

(Обратите внимание, что приведенный выше теоретический код, я набрал его вручную и еще не проверил его – что я буду делать в ближайшее время)

После тестирования

Было несколько небольших ошибок с вышеизложенным, что я обновил, а именно, чтобы получить аргументы php для определенных функций вокруг неправильного пути … После сортировки они работают:

 /// grab the html $html = file_get_contents('http://www.cibap.nl/beheer/modules/roosters/create_rooster.php?element=CR13A&soort=klas&week=37&jaar=2012'); /// start with nothing $table = $start = $end = false; /// 'Vrijdag' should be unique enough, but will fail if it appears elsewhere $pos = strpos($html, 'Vrijdag'); /// find your start and end based on reliable tags if ( $pos !== false ) { $start = stripos($html, '<tr>', $pos); if ( $start !== false ) { $end = stripos($html, '</table>', $start); } } /// make sure we have a start and end if ( $start !== false && $end !== false ) { /// we can now grab our table $html; $table = substr($html, $start, $end - $start); /// convert brs to something that wont be removed by strip_tags $table = preg_replace('#<br ?/>#i', "\n", $table); } if ( $table ) { /// break apart based on rows (a close tr is quite reliable to find) $rows = preg_split('#</tr>#i', $table); /// break apart the cells (a close td is quite reliable to find) foreach ( $rows as $key => $row ) { $rows[$key] = preg_split('#</td>#i', $row); } } else { /// create so we avoid errors $rows = array(); } /// changed this here from a foreach to a for because it seems /// foreach was working from a copy of $rows and so any modifications /// we made to $rows while the loop was happening were ignored. $lof = count($rows); for ( $rkey=0; $rkey<$lof; $rkey++ ) { /// pull out the row $row = $rows[$rkey]; /// step each cell in the row foreach ( $row as $ckey => $cell ) { /// pull out our rowspan value if ( preg_match('/ rowspan=.([0-9]+)./', $cell, $regs) ) { /// if rowspan is greater than one (ie spread across multirows) $rowspan = (int) $regs[1]; if ( $rowspan > 1 ) { /// then copy this cell into the next row down, but decrease it's rowspan /// so that when we find it in the next row we know how many more times /// it should span down. $newcell = preg_replace('/( rowspan=.)([0-9]+)(.)/', '${1}'.($rowspan-1).'${3}', $cell); array_splice( $rows[$rkey+1], $ckey, 0, $newcell ); } } } } /// now finally step the normalised table and get rid of the unwanted tags /// that remain at the same time split our values in to something more useful foreach ( $rows as $rkey => $row ) { foreach ( $row as $ckey => $cell ) { $rows[$rkey][$ckey] = preg_split('/\n+/',trim(strip_tags( $cell ))); } } echo '<xmp>'; print_r($rows); echo '</xmp>'; 

Для извлечения значений используйте анализатор HTML. PHP Простой HTML-парсер стоит того: http://simplehtmldom.sourceforge.net/