Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Регулярка для списка. 
V
    Опции темы
capitan
Дата 27.2.2013, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 27.2.2005
Где: Москва

Репутация: 1
Всего: 13



Друзья, требуется ваша помощь. Что-то я подвис :(

Есть html код:
Код

<dl class="block">
    <dt>Режиссеры</dt>
    <dd><a href="#">Маркос Сига</a></dd> 
    <dd><a href="#">Джон Беринг</a></dd>
    
    <dt>Актеры</dt>
    <dd><a href="#">Нина Добрев</a></dd>
    <dd><a href="#">Пол Уэсли</a></dd>
</dl>


соответственно на выходе нужно получить массив вида:
Код

array(
   'Режиссеры' => array('<dd><a href="#">Маркос Сига</a></dd> ', '<dd><a href="#">Джон Беринг</a></dd>'),
   'Актеры' => array('<dd><a href="#">Нина Добрев</a></dd> ', '<dd><a href="#">Пол Уэсли</a></dd>'),
);

PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 27.2.2013, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



интересная задачка..  smile думал лёгкая... а ведь хрен решишь

вот только так
Код

$str = '
<dl class="block">
    <dt>Режиссеры</dt>
    <dd><a href="#">Маркос Сига</a></dd>
    <dd><a href="#">Джон Беринг</a></dd>

    <dt>Актеры</dt>
    <dd><a href="#">Нина Добрев</a></dd>
    <dd><a href="#">Пол Уэсли</a></dd>
</dl>';

$array = explode('<dt>', $str);

$result = array();

for($i=0; $i < count($array); $i++){
    $b = preg_match('#(.*?)\</dt\>#ui', $array[$i], $tmp1);
    if($b){
        $result[$i]['key'] = $tmp1[1];
        $b = preg_match_all('#(\<dd\>.*?\</dd\>)#ui', $array[$i], $tmp2);
        if($b){
            $result[$i]['value'] = $tmp2[1];
        }
    }
}

print_r($result);


вот только ключи наверное всё таки не могут быть на кириллице.. или я путаю

Добавлено через 6 минут и 32 секунды
я путаю  smile 

тогда так
Код

$str = '
<dl class="block">
    <dt>Режиссеры</dt>
    <dd><a href="#">Маркос Сига</a></dd>
    <dd><a href="#">Джон Беринг</a></dd>

    <dt>Актеры</dt>
    <dd><a href="#">Нина Добрев</a></dd>
    <dd><a href="#">Пол Уэсли</a></dd>
</dl>';

$array = explode('<dt>', $str);

$result = array();

for($i=0; $i < count($array); $i++){
    $b = preg_match('#(.*?)\</dt\>#ui', $array[$i], $tmp1);
    if($b){
        $b = preg_match_all('#(\<dd\>.*?\</dd\>)#ui', $array[$i], $tmp2);
        if($b){
            $result[$tmp1[1]] = $tmp2[1];
        }
    }
}

print_r($result);


Добавлено через 7 минут и 39 секунд
вот что получается
Цитата

Array
(
    [Режиссеры] => Array
        (
            [0] => <dd><a href="#">Маркос Сига</a></dd>
            [1] => <dd><a href="#">Джон Беринг</a></dd>
        )

    [Актеры] => Array
        (
            [0] => <dd><a href="#">Нина Добрев</a></dd>
            [1] => <dd><a href="#">Пол Уэсли</a></dd>
        )
)



Это сообщение отредактировал(а) Gold Dragon - 27.2.2013, 18:32


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Aliance
Дата 27.2.2013, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 2
Всего: 137



Я бы попробовал решить с помощью preg_offset_capture и substr / strpos / strlen
PM MAIL WWW ICQ Skype   Вверх
capitan
Дата 27.2.2013, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 27.2.2005
Где: Москва

Репутация: 1
Всего: 13



Gold Dragon,  Спасибо огромное!!! Будет время, попробую, может по другому можно. Я пытался уместить все в одну регулярку, почти получилось, но на больших данных скрипт вис :(
PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 27.2.2013, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



я что только не пробовал smile
в одну регулярку не уместил никак, принципы разные... вот был бы формат XML то без проблем... да и способов куча

ты покажи свою регулярку может что в голову придут

Добавлено через 1 минуту и 46 секунд
Aliance, будет сложнее, да и убираем проблемы пробельных  и многобайтовых символов


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
capitan
Дата 27.2.2013, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 27.2.2005
Где: Москва

Репутация: 1
Всего: 13



Последнее, после чего все удалил нафиг :(
Код

if(preg_match_all('~(<dt>([^<]+)</dt>\s?)((<dd>.*?</dd>)+)~msi', $str, $q)) {    
    var_dump($q);
}

на больших данный, скрипт тупо отваливается. После этого решил, что в одну врядли получится :(

Gold Dragon, Ваш вариант работает отлично! Единственно, я переписал, в стиле, как привык писать  сам smile
Те же шары, только вид сбоку smile

Код

$array = explode('<dt>', $str);
$result = array();
foreach($array as $key=>$val){  
    if(preg_match('~(.*?)</dt>~ui', $val, $tmp1)){        
        if(preg_match_all('~(<dd>.*?</dd>)~ui', $val, $tmp2)){            
            $result[$tmp1[1]] = $tmp2[1];
        }
    }
}

echo '<pre>';
var_dump($result);


Это сообщение отредактировал(а) capitan - 27.2.2013, 19:10
PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 27.2.2013, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



а почему твой тормозит?
я вот тут малость твой подправил.. а то чтобы работал твой вариант нужно было бы убрать все переносы и пробелы между тэгами smile
Цитата

'~(<dt>.*?</dt>)\s*(<dd>.*?</dd>\s*)+~msi'


Добавлено через 9 минут и 18 секунд
Цитата(capitan @  27.2.2013,  19:52 Найти цитируемый пост)
Те же шары, только вид сбоку
нее.. не мой стиль.. я люблю чтобы код сразу читался даже спустя год и два... И не люблю в условиях функции smile сначала действие, потом проверка...

Добавлено через 11 минут и 58 секунд
кстати, а зачем тебе $key если ты его не используешь?  smile 
Код

foreach($array as $val){



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 27.2.2013, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



тоже предпочитаю  foreach, в примере for использовал для другой цели от которой потом отказался, а функция осталась...  smile 

Решил тесты провести... foreach оказался примерно в 17 раз быстрее for если массив схожей структуры взять


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
capitan
Дата 27.2.2013, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 27.2.2005
Где: Москва

Репутация: 1
Всего: 13



Цитата(Gold Dragon @ 27.2.2013,  19:41)
а почему твой тормозит?
я вот тут малость твой подправил.. а то чтобы работал твой вариант нужно было бы убрать все переносы и пробелы между тэгами smile
Цитата

'~(<dt>.*?</dt>)\s*(<dd>.*?</dd>\s*)+~msi'

А ты сам попробуй smile 
Этот код парсит страницу, к примеру:
http://m.kinopoisk.ru/cast/394375
PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 27.2.2013, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



попробовал  smile 
Цитата

Прекращена работа программы "Apache HTTP Server"


и ты знаешь, а мой мгновенно всё перегнал smile 


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Aliance
Дата 28.2.2013, 11:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 2
Всего: 137



Цитата(Gold Dragon @  27.2.2013,  21:10 Найти цитируемый пост)
Решил тесты провести... foreach оказался примерно в 17 раз быстрее for если массив схожей структуры взять 

не верю smile 
PM MAIL WWW ICQ Skype   Вверх
capitan
Дата 28.2.2013, 11:17 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 27.2.2005
Где: Москва

Репутация: 1
Всего: 13



Цитата(Aliance @ 28.2.2013,  11:02)
Цитата(Gold Dragon @  27.2.2013,  21:10 Найти цитируемый пост)
Решил тесты провести... foreach оказался примерно в 17 раз быстрее for если массив схожей структуры взять 

не верю smile

Тоже странно. http://php.spb.ru/php/speed.html тут проводили тесты, for и while оказались быстрее foreach. 
Причем, еще есть разница  в 
Код

foreach($array as $val)

и
Код

foreach($array as $key=>$val)

При втором варианте время увеличивается ещё.
PM MAIL WWW ICQ   Вверх
Gold Dragon
Дата 28.2.2013, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



Aliance, а как поверишь?  smile 

в общем странно, дома у меня другие результаты были.. на работе разница увеличилась

вот мой тест
Код

$array = array();
for($i=0; $i < 1000000; $i++){
    $array[] = 'qqqqqq';
}

$a = microtime(true);
foreach($array as $value){}
$aa = round((microtime(true) - $a), 5);

$b = microtime(true);
for($i=0; $i < count($array); $i++){}
$bb = round((microtime(true) - $b), 5);

echo 'foreach: ' . $aa .'<br>for: '. $bb;
echo '<hr>'. $bb/$aa;

Апач 2.2.23
PHP 5.4.8

capitan, статейка старенькая и думаю результаты уже поменялись с выходом новых версий PHP

Добавлено через 7 минут и 53 секунды
проверил на нескольких компах на работе.. разница 145-185, 17 даже близко не смог получить smile

Это сообщение отредактировал(а) Gold Dragon - 28.2.2013, 13:36


--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
Aliance
Дата 28.2.2013, 13:41 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 2
Всего: 137



вот это
Цитата

$array = array();
for($i=0; $i < 1000000; $i++){
    $array[] = 'qqqqqq';
}


можно заменить на это:
Код

$array = range(1,  1000000);


и вот это
Цитата

for($i=0; $i < count($array); $i++){}


на это

Код

$len = sizeof(array);
for($i=0; $i < $len; $i++){}
// или вообще на
// for($i = $len; $i--;){}


Ну и если верить тестам по ссылке выше, нужно все же не просто прогонять цикл, а что-то делать с данными. Например вызывать sprintf.

Ну и в целом-то никак не в 17 раз smile

Это сообщение отредактировал(а) Aliance - 28.2.2013, 13:43
PM MAIL WWW ICQ Skype   Вверх
Gold Dragon
Дата 28.2.2013, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Призрачный
****


Профиль
Группа: Экс. модератор
Сообщений: 6753
Регистрация: 1.3.2004
Где: Россия, Тамбов

Репутация: 1
Всего: 71



Aliance, ты прав, упустил такой момент как count. Заменил на твоё и разница сократилась до 2,5 smile

Добавлено через 4 минуты и 47 секунд
Цитата(Aliance @  28.2.2013,  14:41 Найти цитируемый пост)
Ну и если верить тестам по ссылке выше, нужно все же не просто прогонять цикл, а что-то делать с данными. Например вызывать sprintf.

добавил
Код

 $x=sprintf("test%08i",$i);
результаты сравнились практически

заменил на
Код

$x = $i;
разница уже составила 1,6-1,8 раз в пользу foreach



--------------------
Нельзя жить в прошлом, оно уже прошло.
Нельзя жить в будущем, оно ещё не наступило.
Нужно жить в настоящем, помня прошлое и думая о будущем!
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.1089 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.