[Regex] Quote in quote
Ik heb nu dit script:
Code (php)
1
2
3
2
3
<?php
$input = preg_replace("#\[quote=(.*?)\](.*?)\[/quote\]#si", "<div class=\"quote\"><strong>Geplaatst door <a href=\"http://\\1.-weggehaald-.nl/\">\\1</a></strong><br />\\2</div>", $input);
?>
$input = preg_replace("#\[quote=(.*?)\](.*?)\[/quote\]#si", "<div class=\"quote\"><strong>Geplaatst door <a href=\"http://\\1.-weggehaald-.nl/\">\\1</a></strong><br />\\2</div>", $input);
?>
Maar als ik nu twee keer een quote doe werkt het al niet meer, weet iemand waarom?
Gewijzigd op 22/10/2011 20:09:05 door - Raoul -
Wat gebeurt er met de HTML-code dan?
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<div class="quote">
<strong>Geplaatst door <a href="http://-weg-">-weg-</a></strong>
<br />Nieuwe quote<br />
[quote=-weg-]Hello
</div>
</div>
<strong>Geplaatst door <a href="http://-weg-">-weg-</a></strong>
<br />Nieuwe quote<br />
[quote=-weg-]Hello
</div>
</div>
Terwijl ik heb:
[quote=Raoul]Nieuwe quote
[quote=Raoul]Hello[/quote][/quote]
Gewijzigd op 22/10/2011 20:21:32 door - Raoul -
Gewijzigd op 22/10/2011 21:29:46 door Jacco Brandt
recursieve regular expressions, wat je in principe nodig hebt. In combinatie met preg_replace_callback zou dat redelijk te doen moeten zijn. Zie voorbeeld 3.
PHP heeft Code (php)
1
2
3
2
3
<?php
$input = preg_replace_callback("#\[quote=(.*?)\](.*?)\[/quote\]#si", "<div class=\"quote\"><strong>Geplaatst door <a href=\"http://\\1.-doei-.nl/\">\\1</a></strong><br />\\2</div>", $input);
?>
$input = preg_replace_callback("#\[quote=(.*?)\](.*?)\[/quote\]#si", "<div class=\"quote\"><strong>Geplaatst door <a href=\"http://\\1.-doei-.nl/\">\\1</a></strong><br />\\2</div>", $input);
?>
'Requires argument 2' Ik heb toch een argument 2?
Gewijzigd op 22/10/2011 22:13:27 door - Raoul -
preg_replace_callback slikt een functie als replace-argument. Die functie krijgt dan alle matches die de regexp opleverde en moet dan de replacement-string genereren en teruggeven.
Ik snap niks van je uitleg.
Lees dan maar de handleiding en kijk nog eens naar het voorbeeld.
Alsof ik dat nog niet heb geprobeerd? Ik blijf maar diezelfde error krijgen.
De truc is nu om een regular expression te maken die de goeie begin- en end-tag bij elkaar zoekt, en alles wat daartussen zit naar je callback functie stuurt. Die callback functie handelt dat alles wat daartussen zit dan weer af alsof het een nieuw stuk tekst is, en begint dus weer van voor af aan ubb te vervangen. Maar nu niet over het hele document, de hele input, maar alleen over dat kleine stukje tekst dat gepakt werd. Recursief dus.
Of in code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
echo $input = "hallo [quote=a]1 [quote=b]1.1[/quote] [quote=c]1.2 [quote=d]1.2.1[/quote] [/quote] eind 1[/quote] [quote=e]2[/quote]", "\n\n";
function replace_quote_recursive($input)
{
return '
<div class="quote">
<strong>Geplaatst door <a href="#">' . htmlspecialchars($input[1]) . '</a></strong><br>
' . replace_ubb($input[2]) . '
</div>
';
}
function replace_ubb($input)
{
$input = preg_replace_callback(
'#\[quote=(.+?)\]((?:[^[]|\[(?!/?quote(?:=(.+?))?\])|(?R))+)\[/quote\]#si',
'replace_quote_recursive', $input);
// Als je hier bent is alles wat in $input tussen [quote] en [/quote] stond al
// eens hier voorbij geweest. Als daar dus [b] in stond, en hier staat code die
// [b] omschrijft naar <strong>, dan is dat voor die stukken tekst in $input
// al gebeurd.
return $input;
}
echo replace_ubb($input);
?>
echo $input = "hallo [quote=a]1 [quote=b]1.1[/quote] [quote=c]1.2 [quote=d]1.2.1[/quote] [/quote] eind 1[/quote] [quote=e]2[/quote]", "\n\n";
function replace_quote_recursive($input)
{
return '
<div class="quote">
<strong>Geplaatst door <a href="#">' . htmlspecialchars($input[1]) . '</a></strong><br>
' . replace_ubb($input[2]) . '
</div>
';
}
function replace_ubb($input)
{
$input = preg_replace_callback(
'#\[quote=(.+?)\]((?:[^[]|\[(?!/?quote(?:=(.+?))?\])|(?R))+)\[/quote\]#si',
'replace_quote_recursive', $input);
// Als je hier bent is alles wat in $input tussen [quote] en [/quote] stond al
// eens hier voorbij geweest. Als daar dus [b] in stond, en hier staat code die
// [b] omschrijft naar <strong>, dan is dat voor die stukken tekst in $input
// al gebeurd.
return $input;
}
echo replace_ubb($input);
?>
(ik moet toegeven, die regular expression maken die hiervoor nodig was was wat lastiger dan ik in gedachten had)
Het werkt maar er is nog een probleem; in de vorige quote word nu alle html (+ubb) eruit gefilterd dus je ziet nu een lelijke HTML code hoe kan dit?
Als je nu als aller eerste stap, voordat je replace_ubb aanroept (dus ook buiten de functie replace_ubb!) de html eruit filtert, werkt het dan beter?