Преобразовать BBCode [IMG] в <img> - PullRequest
0 голосов
/ 30 октября 2018

Я использую preg_replace для преобразования всех BBCode в HTML, но не могу заставить работать теги img. Вот мой код:

$search = array (
    '/(\[b\])(.*?)(\[\/b\])/m',
    '/(\[i\])(.*?)(\[\/i\])/m',
    '/(\[u\])(.*?)(\[\/u\])/m',
    '/(\[ul\])(.*?)(\[\/ul\])/m',
    '/(\[li\])(.*?)(\[\/li\])/m',
    '/(\[user=)(.*?)(\])(.*?)(\[\/user\])/m',
    '/(\[url=)(.*?)(\])(.*?)(\[\/url\])/m',
    '/(\[url\])(.*?)(\[\/url\])/m',
    '/(\[img=)(.*?)(\])(.*?)(\[\/img\])/m',
    '/(\[quote\])(.*?)(\[\/quote\])/m',
    '/(\[code\])(.*?)(\[\/code\])/m',
);

$replace = array (
    '<strong>$2</strong>',
    '<em>$2</em>',
    '<u>$2</u>',
    '<ul>$2</ul>',
    '<li>$2</li>',
    '<a href="../login/profile?u=$2" target="_blank">$2</a>',
    '<a href="$2" target="_blank">$4</a>',
    '<a href="$2" target="_blank">$2</a>',
    '<img src="$4"></img>',
    '<quote>$2</quote>',
    '<code>$2</code>'
);

$string = preg_replace($search, $replace, $string);

Сейчас он создает тег изображения со ссылкой, но добавляет ] к началу и концу ссылки, чтобы он не отображал изображение правильно.

EDIT:

Это происходит из-за того, что я конвертирую ссылки в теги привязки, и это противоречит внутри [img] BBCode.

$url = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/';

$string = preg_replace($url, '[url=$0]$0[/url]', $string);

1 Ответ

0 голосов
/ 31 октября 2018

Несколько замечаний:

  • Измените разделители вашего шаблона с / на ~, чтобы вам не пришлось экранировать символы /, которые существуют внутри вашего шаблона.
  • Просто не используйте группы захвата для подстрок, которые вы не собираетесь использовать. В ваших шаблонах ни одна из нежелательных подстрок не должна быть заключена в скобки для поддержки логики шаблона.
  • Движок регулярных выражений будет считать ] только концом класса символов, если класс символов открыт. По этой причине я не экранирую символы ].
  • Поскольку вы не используете якоря (^ или $), модификатор шаблона m не нужен.
  • Если вы хотите, чтобы в вашем шаблоне не учитывалась регистр символов, используйте флаг / модификатор шаблона i.
  • После удаления всех лишних групп захвата вам нужно всего лишь использовать $1 в строке замены.
  • После обработки bb-кодированных URL-адресов выполните окончательную проверку для всех URL-адресов, которые еще не преобразованы в html-элементы. (*SKIP)(*FAIL) "дисквалифицирует" эти нежелательные подстроки.

Код: ( Демо )

$bbcodes = [
    'Look at this:https://www.example.com/example?ohyeah=sure#okay this is a raw link',
    'No attibute bbcode url: [url]http://example.com/x1[/url]',
    'A url with link and link text: [url=http://example.com/x2]x2[/url]',
    'Image with "ignorable" text: [IMG=sumpthing.jpg]sumpthing[/IMG]',
    'Image: [img=sumpinelse][/img]'
];

$search = array (
    // ...
    '~\[url=((?:ht|f)tps?://[a-z\d.-]+\.[a-z]{2,3}/\S*?)](.*?)\[/url]~i',
    '~\[url]((?:ht|f)tps?://[a-z\d.-]+\.[a-z]{2,3}/\S*?)\[/url]~i',
    // ...
    '~\[img=(.*?)].*?\[/img]~i',  // if you want the possibility of dot matching newlines, add s pattern modifier
    // ...
    '~(?:<a.*?</a>|<img.*?</img>)(*SKIP)(*FAIL)|\bhttps?://.+?(?=\s|$)~im'  // mop up any remaining links that are not bbtagged
);
$replace = array (
    // ...
    '<a href="$1" target="_blank">$2</a>',
    '<a href="$1" target="_blank">$1</a>',
    // ...
    '<img src="$1"></img>',
    // ...
    '<a href="$0" target="_blank">$0</a>',
);
var_export(preg_replace($search, $replace, $bbcodes));

Выход:

array (
  0 => 'Look at this:<a href="https://www.example.com/example?ohyeah=sure#okay" target="_blank">https://www.example.com/example?ohyeah=sure#okay</a> this is a raw link',
  1 => 'No attibute bbcode url: <a href="http://example.com/x1" target="_blank">http://example.com/x1</a>',
  2 => 'A url with link and link text: <a href="http://example.com/x2" target="_blank">x2</a>',
  3 => 'Image with "ignorable" text: <img src="sumpthing.jpg"></img>',
  4 => 'Image: <img src="sumpinelse"></img>',
)
...