views:

101

answers:

1

Hello,

I'm trying to remove nested quoting from my bulletin board, but I'm having some issues.

Example input:

[quote author=personX link=topic=12.msg1910#msg1910 date=1282745641]

[quote author=PersonY link=topic=12.msg1795#msg1795 date=1282727068]

The message in the original quote

[/quote]

A second message quoting the first one

[/quote]

[quote author=PersonZ link=topic=1.msg1#msg1 date=1282533805]

A random third quote

[/quote]

Example output

[quote author=personX link=topic=12.msg1910#msg1910 date=1282745641]

Message in the second quote

[/quote]

[quote author=PersonZ link=topic=1.msg1#msg1 date=1282533805]

A random third quote

[/quote]

As you can see the nested quote (The original message) is removed, along with the quote tags.

I can't seem to figure it out.

When i try

$toRemove = '(\\[)(quote)(.*?)(\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);

It removes every occurrence of of the quote tag except the first one,

But when i expand the code to:

$toRemove = '(\\[)(quote)(.*?)(\\])(.*?)(\\[\\/quote\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string); 

It stops doing anything at all.

Any ideas on this ?


Edit:

Thanks for your help, Haggi.

Ik keep running in to trouble though.

The while loop around

while ( $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input ) ) {
// replace every occurence
}

causes the page to loop indefinitely, when removed (along with the extra u in quoute), the page doesn't do anything.

I've determined that the cause is the matching

when changed to

$input = preg_replace_callback( '/\[quote(.*?)/i', 'replace_callback', $input );

the code does start working, but when changed to

$input = preg_replace_callback( '/\[quote(.*?)\[\/quote\]/i', 'replace_callback', $input );

It stopts doing anything again.

Also, there is an issue with the undo_replace function as it never finds the stored hash, it only gives warnings about unfound indexes. The regex matching the sha1 isn't working correctly i guess.

The complete code as I have it now:

$cache = array();
$input = $txt;

function replace_callback( $matches ) {
    global $cache;
    $hash = sha1( $matches[0] );
    $cache["hash"] = $matches[0];
    return "REPLACE:$hash";
}



// replace all quotes with placeholders
$input = preg_replace_callback( '/\[quote(.*?)\[quote\]/i', 'replace_callback', $input );

function undo_replace( $matches ) {
    global $cache;
    return $cache[$matches[1]];
}

// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );

// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );

echo $input;

Thanks again for any ideas guys :)

+1  A: 

Hi,

that the first one is the only one that stays is quite easily found out:

'$found++ ? \'\' : \'$1\''

When starting $found is undefined and evaluates to false so the $1 is returned. Then $found gets incremented to 1 ( undefined + 1 = 1 ) so it is greater that zero and every time it gets called it's further incremented. As everything that is different from zero is evaluated as true after that you always get the '' back.

What you want to do is something like this

$cache = array();

function replace_callback( $matches ) {
    global $cache;
    $hash = sha1sum( $matches[0] );
    $cache[$hash] = $matches[0];
    return "REPLACE:$hash";
}

// replace all quotes with placeholders
$count = 0;
do {
    $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input, -1, $count );
    // replace every occurence
} while ($count > 0);

function undo_replace( $matches ) {
    global $cache;
    return $cache[$matches[1]];
}

// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );

// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );

This code is untested as I don't habe PHP at hand to test it. If there are any errors you cannot fix, please just post them here and I will fix them.

Cheers,
haggi

haggi
There are still some issues haggi, but thanks for your help. I've edited the original post with my findings.
Kevin