3

< EDIT >

I Wanted to give a big thank you to all of you who have provided an answer, You have all given me great options. I will play with each and see which one suits my exact needs prior to selecting an answer. I do appreciate all of your responses though, everyone has a different approach to things. =)

bbcodes can (but not always do) include options, an example would be:

[URL="http://google.com"]GOOGLE[/URL]

</ EDIT >

I am currently hiding multiple variables from my string using the following method:

$result = preg_replace('/\[img\](.*)\[\/img\]/im', 'REPLACED', $qry);
$result = preg_replace('/\[url.*\](.*)\[\/url\]/im', 'REPLACED', $qry);

This works, but I would like to be able to do this with just one preg replace, and easily be able to add to it in the future if needed.

I have attempted to use:

$result = preg_replace("#\[/?(img|url)(=\s*\"?.*?\"?\s*)?]#im", 'REPLACED', $qry);

Which is only hiding the tags themselves.

How can I combine these replaces?

DrCustUmz
  • 77
  • 7

3 Answers3

3

preg_replace function can take array of arguments. As an option, you could try with:

$find = ['/\[img\](.*)\[\/img\]/im', '/\[url.*\](.*)\[\/url\]/im'];
$replace = ['REPLACED', 'REPLACED'];

$result = preg_replace($find, $replace, $qry);

I think this way you will have some flexibility to have different replaced values

Urmat Zhenaliev
  • 1,497
  • 8
  • 22
  • This solution works well although I was looking for something more along the lines of `img|url` that way `img|url|its|easy|to|add|tags|to` – DrCustUmz Nov 21 '20 at 13:20
2

Your attempt is very close but you need to use a back reference to first capture group for closing match.

$result = preg_replace('~\[(img|url)\](.*)\[/\1\]~i', 'REPLACED', $qry);

Demo: https://3v4l.org/Ybvh2

The m modifier also has no functionality without an ^ or $. Perhaps you want the s modifier so the . extends to newlines? https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

I also would change the * quantifier to be non-greedy:

$result = preg_replace('~\[(img|url)\](.*?)\[/\1\]~is', 'REPLACED', $qry);

consider https://3v4l.org/8SdNd vs. https://3v4l.org/MC0pf (non greedied).

If you need to distinguish between images and URLs it is probably easiest to have 2 regexs. Functionality with 1 regex though can be achieved with preg_replace_callback:

$result = preg_replace_callback('~\[(img|url)\](.*?)\[/\1\]~is', function($match){
        return $match[1] =='url' ? 'REPLACED url' : 'REPLACED img';
        }, '[img]test[/img][not]img[/not][url]http][/url]');
echo $result;
user3783243
  • 5,368
  • 5
  • 22
  • 41
  • Thank you so much for the reference's and help, although I failed to provide an example of a bbcode thus messing up your answer. bbcodes can contain options like `[url="http://google.com"]` I have updated this in the OP also. https://3v4l.org/scnXJ – DrCustUmz Nov 21 '20 at 13:26
2

You can use

preg_replace('~\[(img|url)\b[^]]*](.*?)\[/\1]~is', 'REPLACED', $qry);

The regex matches:

  • \[ - a [ char
  • (img|url) - Group 1: img or url
  • \b - a word boundary
  • [^]]* - 0 or more chars other than ]
  • ] - a ] char
  • (.*?) - Group 2: any zero or more chars, as few as possible
  • \[/\1] - [/, the same contents as in Group 1, and a ].

See the PHP demo:

$qry = '[url="google.com"]google[/url] and [img]image here[/img]';
echo preg_replace('~\[(img|url)\b[^]]*](.*?)\[/\1]~is', 'REPLACED', $qry);
// => REPLACED and REPLACED
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • This one works for the way you described the qry, but bbcodes as I know them are more along the lines of `[url="http://blah.com"]` and this expression did not work for that, example: https://3v4l.org/scnXJ I have added a bbcode example to the OP also. – DrCustUmz Nov 21 '20 at 13:23
  • You came in first, with a way that's easy to adapt for future use. https://3v4l.org/m0kU3 I apologize for not providing an example bbcode in the first place. Thank you. – DrCustUmz Nov 21 '20 at 13:30