Вопрос по регулярным выражениям
6970 повідомлень
#15 років тому
Не могу понять. Помогите, плз. 
Есть скрипт, заменяющий ссылки в тексте на теги a href.
Исходный текст: посилання (Сайт)
Текст после замены: <a href=http://site.com>Сайт</a>
Замена проводится вот этим кодом:
eregi("((http:)]+) \((.+)\)", $article_in, $url);
if ($url<>"") $article_in=eregi_replace("((http:)]+) \((.+)\)", "<a href=".$url.">".$url."</a> ", $article_in);
Проблема в этой части регулярного выражения:
\((.+)\)
Вроде как оно должно означать "открывающаяся скобка плюс любое количество любых символов плюс закрывающаяся скобка). Но почему-то первая закрывающаяся скобка игнорируется и текст берётся до последней закрывающейся скобки в строке. В доступных мне справочниках по PHP этой оговорки не нашёл.
Что я делаю не так?

2989 повідомлень
#15 років тому
Попробуйте заменить .+ на .*? или (.+) на (.+)?Если не поможет можно попробовать вот так
"((http:)]+) \((.+)\)"
p.s. Вам надо избавиться от "жадности" обработчика регулярного выражения
6970 повідомлень
#15 років тому
Цитата ("elosoft"):Попробуйте заменить .+ на .*?
Выдает ошибку.
Цитата:
или (.+) на (.+)?
Тот же результат, что и с моим выражением.
Цитата:
Если не поможет можно попробовать вот так"((http:)]+) \((.+)\)"
Тут воообще фигня получается: он проглатывает последний символ строки. И всё равно проскакивает первую скобку.
Цитата:
p.s. Вам надо избавиться от "жадности" обработчика регулярного выражения
Вот я и не могу понять, как... Есть, конечно, лобовой способ - прописать все возможные символы, но... неаккуратно как-то.
Главное ведь - стабильно идёт от текущей открывающейся скобки до последней закрывающейся в строке. Соответственно, если пара скобок одна - срабатывает нормально.
И ещё. Если поставить перед закрывающейся кавычкой пробел (т.е. паттерн заканчивается комбинацией "скобка пробел"

6970 повідомлень
2989 повідомлень
#15 років тому
Обработчики для ускорения всегда стараются захвать сразу максимально большой кусок. У Вас это будет от первой подпавшей под выражение открывающей скобки до последней.zzzzzzzzzzzzzzz http:zzzz(первое попавшее) zzzzzzzzz http:zzzz(последнее поппавшее)
получим
первое попавшее) zzzzzzzzz http:zzzz(последнее поппавшее)
Это и есть жадность.
От жадности можно избавить использую знак вопроса или заблокировать повторение каких-то элементов. Ваш запрос я бы начал писать так
"((http:)]+) \((\w+)\)"
А дальше по обстоятельствам...

вот здесь есть хорошие примеры посилання
99 повідомлень
15 повідомлень
6970 повідомлень
#15 років тому
Цитата ("ferggren"):Как вариант - можно использовать рекурсивные выражения
Японский магнитофон!
Оно работает, конечно... а проще это никак не реализовать?

15 повідомлень
6970 повідомлень
#15 років тому
Попробовал вот такое выражение\((.*?)\)
Вроде как символ ? должен отключить жадность. Но получается ошибка REG_BADRPT.

3240 повідомлень
#15 років тому
Цитата ("voron_76"):Вроде как символ ? должен отключить жадность. Но получается ошибка REG_BADRPT.
POSIX функции для работы с регекспами не поддерживают такую возможность. Поэтому лучше используйте функции PCRE, которые поддерживают.
Выше как раз посоветовали вариант с preg_replace (PCRE), а Вы, вероятно, сейчас по-прежнему пробуете вариант с eregi (про который лучше забыть, как про страшный сон, тем более что в PHP 5.3 оно уже объявлено как deprecated, а из PHP 6 вообще будет удалено как мусор).
6970 повідомлень
#15 років тому
Цитата ("tvv"):Цитата ("voron_76"):Вроде как символ ? должен отключить жадность. Но получается ошибка REG_BADRPT.
POSIX функции для работы с регекспами не поддерживают такую возможность. Поэтому лучше используйте функции PCRE, которые поддерживают.
Выше как раз посоветовали вариант с preg_replace (PCRE), а Вы, вероятно, сейчас по-прежнему пробуете вариант с eregi (про который лучше забыть, как про страшный сон, тем более что в PHP 5.3 оно уже объявлено как deprecated, а из PHP 6 вообще будет удалено как мусор).
Понял. Спасибо.

6970 повідомлень
#15 років тому
Вот что получилось в итоге.Скрипт, заменяющий в текстовом файле комбинации вида "http://site.com (сайт)" на ссылку.
<?
$article_in=file("1.txt");
for($i=0; $i < count($article_in); $i++)
{
$url="";
preg_match("/((http:)]+) \((.+?)\)/", $article_in, $url);
if ($url<>"") $article_in=preg_replace("/((http:)]+) \((.+?)\)/", "<a href=".$url.">".$url."</a> ", $article_in);
echo($article_in."<br>");
}
?>
16382 повідомлення
#15 років тому
Цитата ("voron_76"):Вот что получилось в итоге.
Костыль это все. Ссылки должны быть ссылками. Захочется проставить target ссылке или class причепить и все. А для такой вот замены есть bbcode

6970 повідомлень
#15 років тому
Цитата ("frig"):Цитата ("voron_76"):Вот что получилось в итоге.
Костыль это все. Ссылки должны быть ссылками. Захочется проставить target ссылке или class причепить и все. А для такой вот замены есть bbcode
Это не костыль, это решение конкретной задачи. А bbcode вручную вставлять неудобно.

16382 повідомлення
#15 років тому
Цитата ("voron_76"):К тому же, принципиальной разницы, для чего делать обработчик - для bbcode или для такой вот конструкции - по-моему, нет.
Ну почему же? Обработчик для bbcode надо просто готовый взять. Кстати можно и просто поставить WYSIWYG редактор на веб страницу и вообще рулить как вордом.
костыль :P
6970 повідомлень
#15 років тому
Цитата ("frig"):Цитата ("voron_76"):К тому же, принципиальной разницы, для чего делать обработчик - для bbcode или для такой вот конструкции - по-моему, нет.
Ну почему же? Обработчик для bbcode надо просто готовый взять.
И разбираться, каким местом его прикручивать. Ну нафиг. Я не настолько хорошо PHP знаю, мне проще самому написать. Опять же - вставлять руками их всё равно неудобно.
Цитата:
Кстати можно и просто поставить WYSIWYG редактор на веб страницу и вообще рулить как вордом.
Бр-р... У меня был как-то набор макросов для Ворда, которые расставляли HTML-теги в текстовом файле - по сути, тот же WYSIWYG-редактор. Но ведь это же надо ручками всё расставлять. А зачем расставлять ручками, если можно нажать кнопку и всё сделается само? :P
Цитата:
костыль :P
И вообще - не костыль, а учебный полигон. :P
16382 повідомлення
#15 років тому
Цитата ("voron_76"):И вообще - не костыль, а учебный полигон.
А я вот не спорю на счет учебного полигона. Одно другому не мешает. Учебный полигон, а на нем костыль. Как для учебного полигона - полезно. Но все равно костыль.
Цитата ("voron_76"):
И разбираться, каким местом его прикручивать. Ну нафиг.
Там мануалы есть...

6970 повідомлень
#15 років тому
Цитата ("frig"):Цитата ("voron_76"):И вообще - не костыль, а учебный полигон.
А я вот не спорю на счет учебного полигона. Одно другому не мешает. Учебный полигон, а на нем костыль. Как для учебного полигона - полезно. Но все равно костыль.
Это, кстати, не самостоятельный продукт, а часть обработчика, подготавливающего текстовый файл для заливки на страницу. Там только 6, 7 и 8 строчки нужны, они пойдут в основной обработчик. Всё остальное - обрамление для отладки.
А если надо будет какие-то дополнительные параметры к ссылкам прикрутить - я просто ещё условий допишу.
