Convert BBCode [IMG] to <img>

让人想犯罪 __ 提交于 2019-12-24 02:03:06

问题


I'm using preg_replace to convert all BBCode to HTML but can't get img tags to work. Here is my code:

$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);

Right now it creates an image tag with the link in but adds ] to the start and end of the link so it doesn't display the image correctly.

EDIT:

This is cause by me converting links to anchor tags and it's conflicting within the [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:


Several points to make:

  • Change your pattern delimiters from / to ~ so that you don't have to escape the / characters that exist inside your pattern.
  • Simply do not use capture groups on substrings that you don't intend to use. In your patterns, none of the unwanted substrings need to be parenthetically wrapped to maintain pattern logic.
  • The regex engine will only consider ] to be the end of a character class if a character class is opened. For this reason, I am not escaping any ] characters.
  • Because you aren't using any anchors (^ or $), the m pattern modifier is needless.
  • If you want case-insensitivity in your pattern, use the i pattern flag/modifier.
  • After removing all of the excess capture groups, you only need to use $1 in the replacement string.
  • After processing the bbcoded urls, do a final sweep for any urls that are not already converted to html elements. (*SKIP)(*FAIL) "disqualifies" these unwanted substrings.

Code: (Demo)

$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));

Output:

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>',
)


来源:https://stackoverflow.com/questions/53072440/convert-bbcode-img-to-img

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!