Я перестроил все, кроме одной строки, только с URL-адресом.
<?php
$input = "[url=http://stackoverflow.com]stackoverflow[/url]
[url=http://stackoverflow.com]http://stackoverflow.com/damn[/url]
http://stackoverflow.com/ok
[url=http://stackoverflow.com][img]url_to_img[/img][/url]
[url=http://stackoverflow.com][b]stackoverflow[/b][/url]
[url=http://stackoverflow.com][b][u][i]stackoverflow[/i][/u][/b][/url]
[url=http://stackoverflow.com][color=red]stackoverflow[/color][/url]
[url=http://stackoverflow.com][h1][color=red]stackoverflow[/color][/h1][/url]";
$match = [
'/\[url=([^\]]+)\](.*)\[\/url\]/im',
'/\[img\](.*)\[\/img\]/im',
'/\[b\](.*)\[\/b\]/im',
'/\[u\](.*)\[\/u\]/im',
'/\[i\](.*)\[\/i\]/im',
'/\[color=([^\]]+)\](.*)\[\/color\]/im',
'/\[h([1-6])\](.*)\[\/h(?:[1-6])\]/im',
];
$replace = [
'<a href="$1">$2</a>',
'<img src="$1">',
'<strong>$1</strong>',
'<u>$1</u>',
'<em>$1</em>',
'<span style="color:$1;">$2</span>',
'<h$1>$2</h$1>',
];
echo preg_replace($match, $replace, $input);
Это дает следующий результат:
<a href="http://stackoverflow.com">stackoverflow</a>
<a href="http://stackoverflow.com">http://stackoverflow.com/damn</a>
http://stackoverflow.com/ok
<a href="http://stackoverflow.com"><img src="url_to_img"></a>
<a href="http://stackoverflow.com"><strong>stackoverflow</strong></a>
<a href="http://stackoverflow.com"><strong><u><em>stackoverflow</em></u></strong></a>
<a href="http://stackoverflow.com"><span style="color:red;">stackoverflow</span></a>
<a href="http://stackoverflow.com"><h1><span style="color:red;">stackoverflow</span></h1></a>
Тот, который соответствует только URL-адресу, немного сложнее. Это зависит от того, насколько продвинутым вы хотите его сделать. Он может обнаруживать простые вещи, такие как example.com
, или более сложные вещи, такие как ☃.net (что приводит к http://xn--n3h.net/)
Некоторое объяснение
Первое правило, которое мы пытаемся сопоставить и заменить, — это код URL. Мы просто начинаем с поиска внешнего вида [url=
, простого и жестко закодированного. То, что мы ищем дальше, может быть многими вещами, но одно мы знаем точно, что мы должны закончить на ]
. Затем мы можем использовать регулярное выражение, которое говорит: match all but ]
([^\]]+)
Обратите внимание, что я экранировал символ ]
, иначе совпадение не удастся.
Затем я снова ищу все ((.*)
), пока не достигну жестко заданного ожидаемого значения, [/url]
.
Это почти полное правило соответствия для каждого типа bbcode, который вы хотели.
Что касается части замены, вы включаете то, чем они должны быть заменены, просто. Чтобы добавить значения, соответствующие регулярному выражению, используйте $1, $2, ..., $n
. Соответствие определяется моими круглыми скобками.
Например: '/[url=([^]]+)](.*)[/url] /im'
Сегменты в скобках, выделенные полужирным шрифтом, — это сегменты, содержащие значения, которые мы будем получать из $1
и $2
.
Я изо всех сил старался объяснить, как это работает. Если что-то осталось непонятным, укажите на это, и я постараюсь объяснить подробнее
person
Morten
schedule
25.08.2015