[Regex] Quote in quote
Hallo,
Ik heb nu dit script:
Maar als ik nu twee keer een quote doe werkt het al niet meer, weet iemand waarom?
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?
Dit:
Terwijl ik heb:
[quote=Raoul]Nieuwe quote
[quote=Raoul]Hello[/quote][/quote]
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 -
.*? veranderen in .+?. .+? is non-greedy.
Gewijzigd op 22/10/2011 21:29:46 door Jacco Brandt
PHP heeft 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.
Hmm, ik krijg nog steeds een foutmelding.
'Requires argument 2' Ik heb toch een argument 2?
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.
preg_replace_callback vindt een stukje dat overeenkomt, roept dan je callback (je 2e parameter voor preg_replace_callback) aan. Deze functie moet dan het vervangende stukje tekst uitrekenen. Dat geeft 'ie terug, en preg_replace_callback zet het dan als vervanging in de tekst terug. Soort van.
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:
(ik moet toegeven, die regular expression maken die hiervoor nodig was was wat lastiger dan ik in gedachten had)
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)
Bedankt voor je reactie.
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?
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?
Blijkbaar escape je alle html ergens in een van die stappen. Het probleem is, zodra je bij dat quote-filter voorbij bent, zit er html in je tekst. En replace_ubb wordt meerdere keren aangeroepen, dus als je daar je html die erin zit eruit filtert, filter je ook de ubb code html eruit.
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?
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?





