[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Любителям регулярок
Страницы: 1, 2
Invis1ble
Вобщем такая задачка возникла: есть парсер, парсит содержимое title по указанному URL'у.
function parse_title($content)
{
preg_match('#<title[^<]*>(.+)</title>#siU', $content, $matches);
return isset($matches[1]) ? $matches[1] : null;
}

Парсит вполне успешно.
И все бы ничего, но попалась страничка с кодом вида
<!-- <title><data:blog.pageTitle/></title> -->
...
<title>заголовок</title>

ну и парсер естественно вытянул <data:blog.pageTitle/>
задачка: исправить :)
Сам-то я в курсе, как сделать это за два шага. Но чисто спортивный интерес сделать одной регуляркой. Затык в таком warning'е при попытке написать регулярку с просмотром назад и вперед:
Цитата
Warning: preg_match(): Compilation failed: lookbehind assertion is not fixed length at offset ...

Warning мой старый знакомый, но до сих пор не знаю как его победить, а точнее как указать условие :)


Идеи? B)

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

Игорь_Vasinsky
малость модернизировалол ещё и под юникод
  function parse_title($content, $char = null)
{
preg_match('#[^<!\-\- ]<title[^<]*>(.+)</title>#siU'.$char, $content, $matches);
return isset($matches[1]) ? $matches[1] : null;
}

echo parse_title($content, 'u');


ну это если метасимволы в паттерне попадутся да? без экранирования
Цитата

  Warning: preg_match(): Compilation failed: lookbehind assertion is not fixed length at offset ...




Спустя 2 минуты, 38 секунд Игорь_Vasinsky написал(а):
winstona на вас нет laugh.gif



Спустя 5 минут, 58 секунд Игорь_Vasinsky написал(а):
Цитата
Сам-то я в курсе, как сделать это за два шага.

наверн preg_match_all и если в count($matches[1]) > 1

return $matches[1][1] wink.gif

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Invis1ble
Цитата (Игорь_Vasinsky @ 28.11.2012 - 08:55)
малость модернизировалол ещё и под юникод
  function parse_title($content, $char = null)
{
preg_match('#[^<!\-\- ]<title[^<]*>(.+)</title>#siU'.$char, $content, $matches);
return isset($matches[1]) ? $matches[1] : null;
}

echo parse_title($content, 'u');


ну это если метасимволы в паттерне попадутся да? без экранирования
Цитата

  Warning: preg_match(): Compilation failed: lookbehind assertion is not fixed length at offset ...

неверное решение, подходит только для частного случая smile.gif



Спустя 58 секунд Invis1ble написал(а):
Цитата (Игорь_Vasinsky @ 28.11.2012 - 09:01)
Цитата
Сам-то я в курсе, как сделать это за два шага.

наверн preg_match_all и если в count($matches[1]) > 1

return $matches[1][1] wink.gif

нет, удаляем комменты из кода, затем парсим - 2 регулярки

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

Winston
Как насчет такого варианта?
Свернутый текст
$content = '<!-- <title><data:blog.pageTitle/></title> -->
...
тро ло ло, что то еще..
<title>заголовок</title>'
;


preg_match('#^(?:(?<!<!--).)*<title>(.+)</title>(?:(?!-->).)*$#miU', $content, $matches);
echo '<pre>' . htmlspecialchars(print_r($matches, 1)) . '</pre>';


Свернутый текст
Array
(
[0] => <title>заголовок</title>
[1] => заголовок
)
Winston
Или так, если без переносов строки будет
Свернутый текст
$content = '465465456jhkhgfd<!--<title><data:blog.pageTitle/></title>--><a><s& amp; gt;<a>4564</a>...<title>заголовок</title>';
preg_match('#(?:(?<!<!--)\s*)<title>(.+)</title>#isU', $content, $matches);
Invis1ble
Цитата (Winston @ 28.11.2012 - 09:43)
Как насчет такого варианта?
Свернутый текст
$content = '<!-- <title><data:blog.pageTitle/></title> -->
...
тро ло ло, что то еще..
<title>заголовок</title>'
;


preg_match('#^(?:(?<!<!--).)*<title>(.+)</title>(?:(?!-->).)*$#miU', $content, $matches);
echo '<pre>' . htmlspecialchars(print_r($matches, 1)) . '</pre>';


Свернутый текст
Array
(
[0] => <title>заголовок</title>
[1] => заголовок
)

близко, но все равно неправильно. Тест-кейс:
$content = '<!-- <title><data:blog.pageTitle/></title> -->
...
тро ло ло, что то еще.. <!--
<title>заголовок</title>'
;


_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

Winston
Цитата (Invis1ble @ 28.11.2012 - 10:07)
близко, но все равно неправильно. Тест-кейс:

Хм.. У меня на твоем тест-кейсе эта регулярка
#^(?:(?<!<!--).)*<title>(.+)</title>(?:(?!-->).)*$#miU

Выбирает нужный тайтл, у тебя не так? :unsure:
Invis1ble
Цитата (Winston @ 28.11.2012 - 10:16)
Цитата (Invis1ble @ 28.11.2012 - 10:07)
близко, но все равно неправильно. Тест-кейс:

Хм.. У меня на твоем тест-кейсе эта регулярка
#^(?:(?<!<!--).)*<title>(.+)</title>(?:(?!-->).)*$#miU

Выбирает нужный тайтл, у тебя не так? :unsure:

да, выбирает :) а не должна, ибо title закомменчен же получается :)
смысл в том, чтобы вытянуть тот title, который показывался бы в браузере, если б юзверь перешел по урлу :) точнее, тот, который бы увидел гугл к примеру (т.е. javascript и прочие нюансы в расчет не берем)

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

Игорь_Vasinsky
Цитата
неверное решение, подходит только для частного случая

да ну тебя. сам указал текст страницы.

тогда для такой тоже пишите

<html>
<
head>
<!-- <
title> ... </title> -->
<
title>Заголовок</title>


и для такой
<html><head><!-- <title> ... </title> --><title>Заголовок</title>


и для такой

<html>
<
head>
<!-- <
title> ... </title> -->
<
script language....></script>
<
title>Заголовок</title>


и для такой

<html>
<
head>
<!-- <
title> ... </title> -->
<
meta name="author" ...>
<
title>Заголовок</title>


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Игорь_Vasinsky
а может быть и такой

<html>
<
head>
<!-- <
title> ... </title> -->
<!--
Заголовок страниц-->
<
title>Заголовок</title>
<
meta name="author" ...>
....
<
title>Заголовок 2</title>


в том то и дело - человеческий фактор - угадать нельзя все варианты.

можно парсит гугл с выдачей по этой странице или другой поисковик если тока - то реальный заголовок поймать можно.

а так - это баловство.

да и в большенстве случаев title 1 :angry:

_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Invis1ble
Игорь_Vasinsky
да, все правильно smile.gif надо предусмотреть все возможные случаи, код страницы я для примера привел.
не злись biggrin.gif

ЗЫ. Насчет нескольких валидных тегов - берем просто первый.

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

killer8080
Invis1ble
а так?
$content = '<!-- <title><data:blog.pageTitle/></title> --> 
...
тро ло ло, что то еще..
<title>заголовок</title>
<!--hhg <title>bad</title>'
;


preg_match('#^(?:(?:<!--.*-->)*(?<!<!--).)*<title>(.+)</title>(?:(?!-->).)*$#isU', $content, $matches);
echo '<pre>' . htmlspecialchars(print_r($matches, 1)) . '</pre>';
killer8080
еще лучше так
'#^(?:(?:<!--.*-->)*(?<!<!--).?)*<title>(.+)</title>.*$#isU'
Invis1ble
killer8080
Эх, почти
$content = '<!-- <title><data:blog.pageTitle/></title> -->
...
тро ло ло, что то еще..
<!--<title>заголовок</title>
<!--hhg <title>bad</title>'
;

$content = '<!-- <title><data:blog.pageTitle/></title> -->
...
тро ло ло, что то еще..
<title>заголовок</title> -->
<!--hhg <title>bad</title>-->'
;

Ладно, забейте ребята. Я сделал вывод, что мизерный прирост производительности в довольно редкой операции не стоит того геморроя и решил заюзать все-же DOMDocument :) Тем более, есть еще варианты типа <script>var str = '<title>fake title</title>'</script>, которые будут усложнять регулярку в геометрической прогрессии

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

Invis1ble
Всем плюсы посоны cool.gif

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.