0

I have a string that would have a similar pattern as $string below (pulled from forum posts).

$string = "[quote=\"abc123\":27zslwh3]I don't agree with most of the statements made here.[/quote:27zslwh3] I don't think that is very nice of you.";
$pattern = "/\[quote\=.\*\[\/quote.*\]/";
$replace = "";

$updated_text = preg_replace($pattern,$replace,$string);
echo $updated_text;

I am trying to use preg_replace to remove all the text between the opening and closing [quote] tags and echo the remaining string: "I don't think that is very nice of you." only (from $string above).

The pattern I am using for the regular expression is supposed to look for the beginning of the opening [quote] tag, then search through until it finds the closing [quote] tag and the final ] of the tag.

The above doesn't seem to work properly though and I am not too proficient with reg expressions so am stuck here. Any help would be appreciated.

.

NOTE: I tried both codes provided by drew010 and bsdnoobz (thanks for the code and explanations) and it still didn't work. The issue is that I did not capture the $string text correctly. It should read as:

$string = '[quote="abc123":27zslwh3]I dont agree with most of the statements made here.

abc123[/quote:27zslwh3]
I dont think that is very nice of you.';

there are html chars for the double quotes and what appears to be either new line or carriage return characters as well which is probably what prevented the regular expressions submitted below not work for me.

2 Answers 2

2
$string = '[quote="abc123":27zslwh3]I don\'t agree with most of the statements made here.[/quote:27zslwh3] I don\'t think that is very nice of you.';
echo preg_replace('/\[quote.+?\].+?\[\/quote.+?\]/is', '',$string);
// will print: I don't think that is very nice of you.

Note: There are both single quote and double quotes in your input string. This example wraps the input string with single quote, and escape any single quote within the string.

Sign up to request clarification or add additional context in comments.

3 Comments

This answer is at least partially incorrect because regular expressions are greedy by default. The .+ will match everything until the last possible ] so a string like "[quote]first quote[/quote] some text [quote]second quote[/quote]" will be transformed to "". You should replace all your .+s with .+? to make that part of the match non-greedy.
Thank you for your help. I had incorrect data in string (string contains \n or \r) which caused the regular expression you provided to not work with my data. Are there any changes that would work regardless of \n or \r?
thanks, I fixed the quotes in the string and added the s flag and it worked.
2

Here is a pattern that works also:

$pattern = '/\[quote[^\]]*\].*?\[\/quote[^\]]*\]/is';

It will match formats like what you have, or simply bare quotes like [quote]Text...[/quote]

To break it down:

\[quote[^\]]*\] says match text [quote and any character except ] 0 or more times

\] matches the closing ] on the end of the opening [quote] tag.

.*? matches any character 0 or more times. The ? in this context makes this match ungreedy (meaning it will stop when it matches the next part of the pattern first, rather than last.

\[\/quote[^\]]*\] then matches [/quote and any character except ] 0 or more times, and finally we consume the closing ]

5 Comments

Also, since you are new to regular expressions, note the usage of .*?: this says, match any character any number of times, but in a non-greedy way. Regular expressions are greedy by default, meaning they will match as much as possible. If you had only put .*, then a string like "[quote]first quote[/quote] some text [quote]second quote[/quote]" would be transformed to "".
@zi42 Thanks for giving them the good explanation on greedyness :) A subtle, but important aspect of the regex.
Thank you for your help. I had incorrect data in string (string contains \n or \r) which caused the regular expression you provided to not work with my data. Are there any changes that would work regardless of \n or \r?
I fixed the quotes in the string and added the s flag and this regular expression worked as well ... thanks
@user1427489 Nice find on the s modifier (PCRE_DOTALL) which is required if you want . to match newlines as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.