Регулярное выражение URL-BBCode

В настоящее время я пытаюсь получить URL-адрес из BBCode. Для этого есть четыре возможности, и это моя текущая проблема:

[url]http://stackoverflow.com/[/url]
[url='http://stackoverflow.com/']http://stackoverflow.com/[/url]
[url="http://stackoverflow.com/"]http://stackoverflow.com/[/url]
[url=http://stackoverflow.com/]http://stackoverflow.com/[/url]

Мне нужны оба. Это то, что у меня есть до сих пор:

/\[url(?:\=\'([^\'"]+)\')?](.+?)\[\/url]/i

Но это работает только в случаях 1 и 2.

РЕДАКТИРОВАТЬ:

Это работает лучше:

/\[url(?:\=(?:[\"|'])?(.*)(?:[^[]+)?)?\](.*)\[\/url\]/i

Но все же не идеально.

РЕДАКТИРОВАТЬ:

Думаю, я понял. Возможно, потребуется некоторая оптимизация, но, похоже, это работает:

/\[url(?:\=("|\'|)?(.*)?\1)?\](.*)\[\/url\]/i

См. regexp-tester.


person user2557188    schedule 06.07.2013    source источник
comment
возможный дубликат REGEX для ссылок bbcode + URL-адреса, отличные от bbcode   -  person PeeHaa    schedule 07.07.2013
comment
Не совсем, но близко   -  person user2557188    schedule 07.07.2013


Ответы (2)


Вы можете использовать этот шаблон:

$pattern = '~\[url(?|=[\'"]?([^]"\']+)[\'"]?]([^[]+)|](([^[]+)))\[/url]~';
$replacement = '<a href="$1">$2</a>';

$result = preg_replace($pattern, $replacement, $subject);

Идея состоит в том, чтобы сохранить номера групп для каждой ветви чередования, используя функцию сброса ветвей. Таким образом, группа 1 всегда содержит URL-адрес, а группа 2 — описание ссылки. При отсутствии описания вместо него используется адрес, поэтому адрес дважды заключен в группу захвата для второй ветки.

person Casimir et Hippolyte    schedule 07.07.2013

Попробуйте это, это сработает

<?php
  $urlsearch  = "(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?";
  $text = preg_replace( "/\[url\]($urlsearch)\[\/url\]/", "<a href=\"$1\">$1</a>", $text );
  $text = preg_replace( "(\[url\=[\"']?($urlsearch)[\"']?\](.+?)\[/url\])", "<a href=\"$1\">$5</a>", $text );

  print_r( $text );
?>
person bystwn22    schedule 06.07.2013
comment
Похоже, это перебор для моего случая;) Тай в любом случае. - person user2557188; 07.07.2013
comment
просто попробуйте с некоторыми сложными URL-адресами;) - person bystwn22; 07.07.2013
comment
Проблема не в URL. Мне просто нужно содержимое BBCode, которое также может быть не URL-адресом (поэтому я просто использую .*). - person user2557188; 07.07.2013