Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Регулярное выражение для оборачивания ссылок
Форумы портала PHP.SU » PHP » Регулярные выражения » Регулярное выражение для оборачивания ссылок

Страниц (1): [1]
 

1. calipso - 05 Декабря, 2009 - 14:21:38 - перейти к сообщению
Добрый день!

Есть задача: обернуть ссылки bb-кодами, например чтобы
стало
CODE (text):
скопировать код в буфер обмена
  1. [url="http://ya.ru"]http://ya.ru[/url]
.

Вопрос заключается в следующем: как обернуть только не обёрнутые ссылки, т.е. если уже ссылка обёрнута - она не оборачивалась. Т.е., при виде ссылки
CODE (text):
скопировать код в буфер обмена
  1. [url="http://ya.ru"]http://ya.ru[/url]
или
CODE (text):
скопировать код в буфер обмена
  1. <a href="http://ya.ru">http://ya.ru</a>
ничего не происходило.

Как это лучше и правильнее сделать?
2. trot - 05 Декабря, 2009 - 14:45:09 - перейти к сообщению
Мне кажется такую задачу не решить одним действием.
Я бы ее решал так.
1. Найти все обернутые ссылки, вырезать их и запомнить в массиве, а на место ссылок вставить метки, ассоциированную с индексами в массиве.
2. Найти все оставшиеся ссылки (т.е. не обернутые) и их обернуть.
3. Вставить из массивы вырезанные ранее ссылки.
Вот и все.

Считаю, что необходимо обратить на следующие особенности.
а) будут ли в исходном тексте комментарии, в которых могут встречаться ссылки, и что в этом случае нужно делать.
б) обратить внимание на то, что ссылки могут встречаться, как в кавычках, так и в апострофах (это относится скорее всего к обернутым ссылкам).
3. Champion - 05 Декабря, 2009 - 14:47:28 - перейти к сообщению
в регулярках можно использовать утверждения. В твоем случае ты долже написать устовие, что слева нету [url=". Попробуй сам, а если не получится, поправим.
4. calipso - 05 Декабря, 2009 - 15:01:21 - перейти к сообщению
Спасибо за быстрые ответы Улыбка

trot пишет:
Мне кажется такую задачу не решить одним действием.

Я тоже сначала думал в данном направлении, но стало получатся громоздко и выходить за пределы решения при помощи регулярного выражения Улыбка

Champion пишет:
Попробуй сам, а если не получится, поправим.

Набросал
CODE (text):
скопировать код в буфер обмена
  1. $to = preg_replace('/(?<!(\[url=)|\[url="|<a href|<a href=")((https?|ftp)):\/\/([-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|])(?<!\[\/url\])/i', '[url="\0"]\0[/url]', $from);
- тяжеловато, но хоть с какой-то проверкой валидности URL. Всё бы было ничего, но текст типа
CODE (text):
скопировать код в буфер обмена
  1. [url="http://ya.ru/index.html"]http://ya.ru/index.html[/url]
стал превращаться в
CODE (text):
скопировать код в буфер обмена
  1. [url="http://ya.ru/index.html"][url="http://ya.ru/index.html"]http://ya.ru/index.html[/url][/url]

Т.е., в первой чаасти строки [url="http://ya.ru/index.html"] URL не обрабатыватся (как и должно быть), а вот после - http://ya.ru/index.html[/url] - обрабатыватся.

Как быть?
5. Champion - 05 Декабря, 2009 - 15:53:56 - перейти к сообщению
Тогда еще утверждение относительно [/url] справа от ссылки напиши.
6. calipso - 05 Декабря, 2009 - 15:56:39 - перейти к сообщению
Champion пишет:
Тогда еще утверждение относительно [/url] справа от ссылки напиши.

А это
не считается?
7. Champion - 05 Декабря, 2009 - 16:14:49 - перейти к сообщению
а, я не увидел. Считается, только без <. А то оно всегда ложным будет, потому что ты утверждаешь как бы налево. А надо направо.
8. trot - 06 Декабря, 2009 - 23:41:55 - перейти к сообщению
Предлагаю следующий варинат

CODE (text):
скопировать код в буфер обмена
  1.  
  2. $a='[url="http"]http[/url]
  3. http';
  4.  
  5. $a=preg_replace('/(?:(?<=\[url=)(?:"http"])?(?:http))|(http)/e','("\\1")?("[url=\"\\1\"]\\1[/url]"):("\\0")',$a);
  6.  


Если вметсо http вставить шаблон ссылки, получиться тяжеловато.
А если еще попытаться учесть апострофы, тогда задача не имеет решения,
потому что функция preg_replace начинает заниматься дополнительным экранированием.

Варинат предложенный ранее я считаю менее тяжелым чем этот.
9. Phantik - 07 Декабря, 2009 - 09:44:05 - перейти к сообщению
Сделай в два хода:
1 вырежи все обертки из обернутых ссылок, сохрани в промежуточной строке(файле)
2 оберни все ссылки в промежуточном файле.
Думаю что регулярки для первого и второго случая будут не сложные.
10. calipso - 07 Декабря, 2009 - 11:06:45 - перейти к сообщению
trot пишет:
Предлагаю следующий варинат

Спасибо за вариант, попробую поковырять.

Phantik пишет:
Сделай в два хода

Да как-то не особо хочется в несколько заходов делать Недовольство, огорчение

Почему всё же не работает так как надо
CODE (text):
скопировать код в буфер обмена
  1. $to = preg_replace('/(?<!(\[url=)|\[url="|<a href=|<a href=")((https?|ftp)):\/\/([-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|])(?!(\[\/url\]))/i', '[url="\0"]\0[/url]', $from);
?

Вроде же
CODE (text):
скопировать код в буфер обмена
  1. (?!(\[/url\]))
есть для проверки на закрывающий [/url], но не обрабатывается как нужно. Огорчение

 

Powered by ExBB FM 1.0 RC1