| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
VolCh
Зарегистрирован: 07.07.2008 Сообщения: 2
|
Добавлено: Пн Июл 07, 2008 05:57 Заголовок сообщения: Парсинг HTML таблицы, что я делаю не так? |
|
|
В сотый, наверное, раз за 8 лет пытаюсь освоить регулярки, и в сотый раз не понимаю ни черта на php.net, хоть и по-русски теперь написано (когда-то со словарем переводил).
| PHP: |
- $str='<body>text<table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table>text</body>';
- $pattern='/<table>(<tr>(<td>(.*?)<\/td>)*?<\/tr>)*?<\/table>/';
-
- preg_match_all($pattern,$str,$matches,PREG_SET_ORDER);
-
- print_r ($matches);
|
По задумке моей должен вывести хоть как-то в $matches 1,2,3,4, причем в двухмерном виде
Выводит
| PHP: |
- Array
- (
- [0] => Array
- (
- [0] => <table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table>
- [1] => <tr><td>3</td><td>4</td></tr>
- [2] => <td>4</td>
- [3] => 4
- )
-
- )
|
то есть выводит только последнее найденное.
Собственно, что я делаю не так? Нужно получить в итоге двумерный массив ((1,2),(3,4)) (естественно если таблица 10х10 будет, то и массив 10х10 регулярка должна создавать). Интересует именно использование регулярок, а точнее одного регулярного выражения, а потом простая ""конвертация" в итоговый массив. Всякими другими способами задачу решить могу, например через XSLT :) Да и с регулярками рекурсивно их "натравливая" могу, чтобы вырезать сначала table, потом tr, потом td, а вот чтобы одной никак :( Подскажите, пожалуйста, как сделать одной. Переносы строк, регистры и прочее не нужно учитывать, с этим разберусь, мне бы принцип понять. |
|
| Вернуться к началу |
|
 |
Google Помошник
Только для не зарегистрированных пользователей |
|
Ti

Зарегистрирован: 03.07.2006 Сообщения: 2346 Откуда: d1.ru, Екатеринбург
|
Добавлено: Пн Июл 07, 2008 08:35 Заголовок сообщения: |
|
|
Итак, что Вы делаете не так:
1. preg_match_all ищет все соответствия регулярному выражению в $str (в отличии preg_match который найдет только первое)
В вашем случае всему шаблону соответствует целая таблица - результатом может быть много таблиц, а не 10x10 одной таблицы.
2. RegExp выражение никак не влияет на многомерность результата.
Массив будет или одномерный (preg_match) или двумерный (preg_match_all)
3. выражение (.)* в результате всегда будет представленно одим элеменом, а не множеством совпадений
| PHP: |
- <?
- preg_match('#(.)*#', 'text text text', $matches);
- array('text text text', 't');
- array('t', 'e', 'x', 't', ' ', 't', 'e', 'x', 't')
|
В итоге, получить одним регулярным выражением "в итоге двумерный массив ((1,2),(3,4))" нелья.
Решение в лоб:
1. получаем таблицу
2. получаем строки таблицы
3. получаем значения
При условии что в $str одна таблица можно получить результат одним регулярным выражением с небольшими телодвижениями:
| PHP: |
- <?
- $str='<body>text<table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table>text</body>';
- $pattern = '#(<tr>)?<td>(.*?)</td>#';
- preg_match_all($pattern,$str,$matches);
-
-
- array(
- 0 =>
- array (
- 0 => '<tr><td>1</td>',
- 1 => '<td>2</td>',
- 2 => '<tr><td>3</td>',
- 3 => '<td>4</td>',
- ),
- 1 =>
- array (
- 0 => '<tr>',
- 1 => '',
- 2 => '<tr>',
- 3 => '',
- ),
- 2 =>
- array (
- 0 => '1',
- 1 => '2',
- 2 => '3',
- 3 => '4',
- ),
- );
-
-
- $i = -1;
- $result = array();
- foreach($matches[2] as $key=>$value) {
- if ($matches[1][$key]) $i++;
- $result[$i][] = $value;
- }
-
-
- array (
- array ('1','2'),
- array ('3','4'),
- );
|
_________________ этой подписи здесь нет! |
|
| Вернуться к началу |
|
 |
VolCh
Зарегистрирован: 07.07.2008 Сообщения: 2
|
Добавлено: Пн Июл 07, 2008 19:29 Заголовок сообщения: |
|
|
| Ti писал(а): |
1. preg_match_all ищет все соответствия регулярному выражению в $str (в отличии preg_match который найдет только первое)
В вашем случае всему шаблону соответствует целая таблица - результатом может быть много таблиц, а не 10x10 одной таблицы.
2. RegExp выражение никак не влияет на многомерность результата.
Массив будет или одномерный (preg_match) или двумерный (preg_match_all) |
Первое уже понял, а вот второе надеялся, что поддерживается многомерность, то есть вложенные скобки при повторяющихся частях будут разворачиваться в двумерный массив какой-то для каждого повторения
| Ti писал(а): |
Решение в лоб:
1. получаем таблицу
2. получаем строки таблицы
3. получаем значения
|
Первое что в голову пришло, думал, что красивее можно сделать (хотя Ваш код красивый и его использую сейчас же, если можно) - похоже, что переоценивал регулярные выражения и обычная практика для "универсального" парсера: сначала выбираем общий блок в котором есть повторяющиеся элементы (при этом неповторяющиеся, например, название статьи, можем сразу запомнить), а потом последовательно уточняем (углубляем) повторяющиеся (например, отдельные абзацы), выбирая из уже выбранного (и запомненного средствами PHP). |
|
| Вернуться к началу |
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|