Jump to content

[SOLVED] preg_replace question...


TreColl

Recommended Posts

I am currently creating a very simple forum script in PHP/MySQL for my site...

 

I have obtained a simple function to parse BBCode.

Part of the function allows users to post in  [ quote] boxes to quote stuff!

 

However my problem is that, at current, if two [ quote] boxes are inside each other, only one will show correctly. As though it is ignoring one of the repeated opening [ quote] boxes.

 

Here is the code for the function (only the quote section)

 

// Declare the format for [quote] layout
	$QuoteLayout = '<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
						<tr>
							<td class="quotecodeheader"> Quote:</td>
						</tr>
						<tr>
							<td class="quotebody">$1</td>
						</tr>
				   </table>';

	// Check for [quote] text
	$Text = preg_replace("/\[quote\](.+?)\[\/quote\]/is", "$QuoteLayout", $Text);

$Text is assigned when the function is called, for example BBCode("This is $Text"); if you get what I mean...

 

 

Any help on getting two or more

areas to show up inside each other would be very helpful.

 

Many Thanks

TreColl

Link to comment
Share on other sites

don't know for sure, but have an idea.

 

I think you are going to want to formulate your regex using lookbehinds such that it catches the 'outside' tags.  Right now with nested tags, the regex picks up the first opening tag and the first closing tag.  This leaves the inner qoute with an opening tag and not closing tag and and extra closing tag at the end.  (use preg_match and see what I mean).

 

You need to have the regex look for the opening quote tag from the front and the closing quote tag from the rear of the string.

 

Once you can do that, I would write a self recursive function.  It would search the text string for the quote tags and if it finds them replace the block with the table (like you have) THEN call itself on the new string.  It should continue to dig deeper and deeper until it runs out of tags, then exits.  That is if there isn't a fancy way of having regex do it for you (which there very well might be)

Link to comment
Share on other sites

something like this should work:

 

<?php

function transQuote($text){

    $QuoteLayout = '<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
						<tr>
							<td class="quotecodeheader"> Quote:</td>
						</tr>
						<tr>
							<td class="quotebody">$1</td>
						</tr>
				   </table>';

$pattern = "/\[quote\](.*)\[\/quote\]/is";

if(preg_match($pattern,$text)){
	$text = transQuote(preg_replace($pattern, "$QuoteLayout", $text));
 }
return $text;

}	
?>

 

$Text = '[quote][quote]This is a quote[/quote][/quote]';

echo transQuote($Text);

 

gives

 

<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
      <td class="quotecodeheader"> Quote:</td>
</tr>
<tr>
	<td class="quotebody">
                             <table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
			<tr>
				<td class="quotecodeheader"> Quote:</td>

			</tr>
			<tr>
				<td class="quotebody">This is a quote</td>
			</tr>
		      </table>
                 </td>
</tr>
</table>

 

Your regex was actually okay....you just needed to make it greedy

 

NOTE:  this will only handle a single set of nested tags.  It doesn't work on "

stuff
more stuff
", but the approach is valid.  You would just need to use preg_match_all to pull out the subexpressions and act on them individually.
Link to comment
Share on other sites

something like this should work:

 

<?php

function transQuote($text){

    $QuoteLayout = '<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
						<tr>
							<td class="quotecodeheader"> Quote:</td>
						</tr>
						<tr>
							<td class="quotebody">$1</td>
						</tr>
				   </table>';

$pattern = "/\[quote\](.*)\[\/quote\]/is";

if(preg_match($pattern,$text)){
	$text = transQuote(preg_replace($pattern, "$QuoteLayout", $text));
 }
return $text;

}	
?>

 

This method seems to work correctly, the only problem is that is *printing* the HTML instead on using it.

 

As in... I can see..

 

<table> etc....

as apoosed to seeing a table!

 

Any Ideas?

Link to comment
Share on other sites

Here's a way to do tags that are nested. I've not seen this elsewhere, but I *think* it would work.

 

Handle the QUOTE and /QUOTE conversions individually. Obviously, if someone had more opening tags than closing tags, this might cause a problem. But I think that would be rare.

 

What do ya' think?

Link to comment
Share on other sites

i haven't worked out the regex yet, but it might be easier to write it from the inside out.

 

build a regex that matches to roughly

 


[quote]anything but quote tags[/quote]

 

so that it only matches the innermost tags, replaces them, then runs again.

Link to comment
Share on other sites

Here's a way to do tags that are nested. I've not seen this elsewhere, but I *think* it would work.

 

Handle the QUOTE and /QUOTE conversions individually. Obviously, if someone had more opening tags than closing tags, this might cause a problem. But I think that would be rare.

 

What do ya' think?

 

What a simple and neat solution. Why haven't I thought of that before! Example for the OP:

 

<?php
function bb2html($text) {
$find = array(
	'~\[quote\]~is',
	'~\[/quote\]~is'
);
$replace = array(
	'<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
	<td class="quotecodeheader"> Quote:</td>
</tr>
<tr>
	<td class="quotebody">',
	'</td>
</tr>
</table>'
);
return preg_replace($find, $replace, $text);
}
echo bb2html('[quote][quote]This is a quote[/quote][/quote]another quote follows[quote]quot.[/quote]');
?>

Link to comment
Share on other sites

Here's a way to do tags that are nested. I've not seen this elsewhere, but I *think* it would work.

 

Handle the QUOTE and /QUOTE conversions individually. Obviously, if someone had more opening tags than closing tags, this might cause a problem. But I think that would be rare.

 

What do ya' think?

 

What a simple and neat solution. Why haven't I thought of that before! Example for the OP:

 

<?php
function bb2html($text) {
$find = array(
	'~\[quote\]~is',
	'~\[/quote\]~is'
);
$replace = array(
	'<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
	<td class="quotecodeheader"> Quote:</td>
</tr>
<tr>
	<td class="quotebody">',
	'</td>
</tr>
</table>'
);
return preg_replace($find, $replace, $text);
}
echo bb2html('[quote][quote]This is a quote[/quote][/quote]another quote follows[quote]quot.[/quote]');
?>

 

You two are geniouses... This works a treat!! Many Thanks!!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.