[php] Reguliere expressie verkeerd uitgevoerd

Pagina: 1
Acties:
  • 107 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • rogierslag
  • Registratie: Maart 2005
  • Laatst online: 14-10-2024
In een website die ik aan het maken ben heb ik een uitleg over de "soort" bbcode die ik gebruik.

De functie die deze code parsed is
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
31
32
#direction 1 parsed bbcode naar html
#direction 2 parsed html naar bbcode (depaced)
#direction 3 verwijdert bbcode in een voorvertoning (slechts aantal tags)

function bbcode($input,$direction = 1)
    {
    #verwijderen regeleinden
    $input = str_replace("\r\n",'',$input);
    if($direction == 1)
        {
        #We gaan bbcode omzetten in html
        $aToReplace = array('/\[b\](.+?)\[\/b\]/','/\[i\](.+?)\[\/i\]/','/\[u\](.+?)\[\/u\]/','/\[url=(http:\/\/)*(.+?)\](.+?)\[\/url\]/','/\[url\](http:\/\/)*(.+?)\[\/url\]/','/\[pagebreak\]/','/\[list\](.+?)\[\/list\]/','/\[sublist\](.+?)\[\/sublist\]/','/\[\*\](.+?)\[\/\*\]/','/\[enter]/','/\[route\.item\](.+?)\[\/route\.item\]/','/\[route\.list\](.+?)\[\/route\.list\]/');
        $aReplacement = array('<b>\\1</b>','<i>\\1</i>','<u>\\1</u>','<a href="http://\\2" target="_blanc" title="\\3">\\3</a>','<a target="_blanc" href="http://\\2">\\2</a>','<p class="pagebreak"></p>','<ul class="voorwaarden_list">\\1</ul>','<li><ul class="voorwaarden_sublist">\\1</ul></li>','<li>\\1</li>','','<h3 class="routebeschrijving_beschrijving">\\1</h3>','<ul class="routebeschrijving_list">\\1</ul>','<ul\\1\\2</ul>');
        }
    elseif($direction == 2)
        {
        #We zetten html om in bbcode. depraced, maar zonde om weg te gooien
        $aToReplace = array('/\<b>(.*)?<\/b>/','/\<i>(.*)?<\/i>/','/\<u>(.*)?<\/u>/','/\<a href="(.*)?" target="_blanc" title="(.*)?">(.*)?<\/a>/','/\<a target="_blanc" href="(.*)?">(.*)?<\/a>/','/\<p class="pagebreak"><\/p>/','/\<ul class="voorwaarden_list">/','/\<\/ul>/','/\<ul class="voorwaarden_sublist">/','/\<\/ul>/','/\<li>/','/\<\/li>/');
        $aReplacement = array('[b]\\1[/b]','[i]\\1[/i]','[u]\\1[/u]','[url=\\1]\\2[/url]','[url]\\1[/url]','[pagebreak]','[list]','[/list]','[sublist]','[/sublist]','[*]','[/*]');
        }
    elseif($direction == 3)
        {
        #We strippen bbcode voor een voorvertoning
        #We laten de vervaning voor [url], [url=*] en [pagebreak] weg. Deze worden dan gewoon leeggelaten
        $aToReplace = array('/\[b\](.+?)\[\/b\]/','/\[i\](.+?)\[\/i\]/','/\[u\](.+?)\[\/u\]/','/\[url=(http:\/\/)*(.+?)\](.+?)\[\/url\]/','/\[url\](http:\/\/)*(.+?)\[\/url\]/','/\[pagebreak\]/','[list]','[/list]','[sublist]','[/sublist]','[*]','[/*]');
        $aReplacement = array('\\1','\\1','\\1');
        }
    else
        return FALSE;
    $output = preg_replace($aToReplace,$aReplacement,$input);
    return $output;
    }


Nou wil ik op een pagina verschillende soorten combineren. Dit is de bbcode:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[b]Dit is een voorbeeld en een test van onze BBCode[/b]
Dit is een [i]test[/i] van de [u]geheime[/u] functies van [url]www.rogierslag.be[/url]
Straks presenteren we vol trots onze [url=http://www.rogierslag.be]nieuwe website[/url]!
De route is niet zo moeilijk: 
We hebben wel een aantal voorwaarden:
[list]
[*]De bedingen in deze algemene voorwaarden zijn mede gemaakt ten behoeve van de maten van *, de bestuurders van de praktijkvennootschappen en van al diegenen die voor de maatschap werkzaam zijn.[/*] 
[sublist]   
    [*]Alle opdrachten worden uitsluitend aanvaard en uitgevoerd door de maatschap*. De toepasselijkheid van de artikelen 7:404 en 7:407 lid 2 BW wordt uitdrukkelijk uitgesloten.[/*]
    [*]Het staat * vrij verleende opdrachten onder haar verantwoordelijkheid door de door haar aan te wijzen bestuurders van praktijkvennootschappen, maten en personeelsleden van * te laten uitvoeren, in voorkomend geval met inschakeling van hulppersonen en derden.[/*]   
[/sublist]
[/list]

[route.item]Vanuit de richting Eindhoven:[/route.item]
    [route.list]
    [*]Neem de afslag Weert-Noord richting Weert.[/*]
    [*]Vervolgens vervolgt u deze weg (de Eindhovenseweg), in de richting van het centrum van Weert, tot aan de tweede rotonde. [/*]
    [*]Bij de tweede rotonde rijdt u naar rechts de Schoutlaan op, waarna u het kantoor aan de linker zijde aantreft.[/*]
[/route.list]


Om de regeleinden netjes te krijgen wordt nl2br uitgevoerd voordat de bbcode naar de function bbcode wordt omgeleid.

Voor de leesbaarheid is het mogelijk om enters te plaatsen in de [route.list], de [list] en de [sublist] tag. Omdat deze normalitair alleen op een speciale pagina worden gebruikt is dit geen probleem. Er wordt dan gewoon geen nl2br over de input gehaald.

Nou wil mijn opdrachtgever dus de boel wél samen gaan gebruiken, waardoor de hele <ul> tags (in de HTML) vol staan met <br /> tags die er niet horen en het hele CMS in de war gooien (de layout iig).

nou dacht ik dit op met de volgende regel in bbcode() op te lossen
PHP:
1
$output = preg_replace('/\<ul(.+?)>(.+?)<br \/>(.+?)<\/ul>/','<ul\\1>\\2\\3</ul>',$output);


Helaas stript deze de <br /> tags er niet netjes uit (deze regel staat vóór de return, dus er zijn <br /> tags aanwezig.

Ik heb geen idee meer hoe ik dit anders kan doen en ik ben er al dik twee uur mee bezig.

Weet iemand misschien hoe de reguliere expressie verandert moet worden zodat de <br /> in een <ul> tag netjes wordt gestript? (totaal andere oplossing is ook welkom.

Acties:
  • 0 Henk 'm!

Verwijderd

Met preg_replace kun je gewoonweg geen hele slimme UBB parser maken. Als je een stack-based parser had gemaakt (eerst de input opdelen in tokens, vervolgens alle tokens aflopen en bijhouden in welke context je zit), dan was dit niet zo'n probleem geweest.

Acties:
  • 0 Henk 'm!

Verwijderd

En waarom het wiel opnieuw uitvinden?

http://www.oisyn.nl/articles.php/12

Acties:
  • 0 Henk 'm!

Verwijderd

Omdat dat niet gratis is voor commerciële doeleinden?

Acties:
  • 0 Henk 'm!

  • rogierslag
  • Registratie: Maart 2005
  • Laatst online: 14-10-2024
Ik heb het uiteindelijk maar gewoon dirty gedaan.

Ik ben er alles behalve tevreden over maar het is beter dan niks
PHP:
1
$output = preg_replace('@>(\040|\t)*(<br \/>|<br>)(\t|\040)*<@', '><', $output);

Acties:
  • 0 Henk 'm!

  • imp4ct
  • Registratie: November 2003
  • Laatst online: 06-09 22:19
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
31
32
33
34
35
36
37
38
39
<?
//STEP 4
//checks the bbcode for faults
//will lowercase every bbtaggs
function print_texttobb($text)
{
  $bbtext = null;
  
  $bbtext = ereg_replace("\[[B]\]","[b]",$text);
  $bbtext = ereg_replace("\[/[B]\]","[/b]",$bbtext);
  $bbtext = ereg_replace("\[[I]\]","[i]",$bbtext);
  $bbtext = ereg_replace("\[/[I]\]","[/i]",$bbtext);
  $bbtext = ereg_replace("\[[U]\]","[u]",$bbtext);
  $bbtext = ereg_replace("\[/[U]\]","[/u]",$bbtext);
  $bbtext = preg_replace("#\[(u|U)(r|R)(l|L)(=([^\[\]]*))?\]([^\[\]]*)\[/(u|U)(r|R)(l|L)\]#e", "'[url=' . ('\\4' == '' ? '\\6' : '\\5') . ']\\6[/url]'",$bbtext);
  $bbtext = preg_replace("#\[(i|I)(n|N)(u|U)(r|R)(l|L)(=([^\[\]]*))?\]([^\[\]]*)\[/(i|I)(n|N)(u|U)(r|R)(l|L)\]#e", "'[inurl=' . ('\\4' == '' ? '\\6' : '\\5') . ']\\6[/url]'",$bbtext);
  $bbtext = preg_replace("#\[(m|M)(a|A)(i|I)(l|L)\]#e", "'[mail]'",$bbtext);
  $bbtext = preg_replace("#\[/(m|M)(a|A)(i|I)(l|L)\]#e", "'[/mail]'",$bbtext);
  return($bbtext);
}

//STEP 5
//script that transforms the bbcode to html
//possible bbtags :
//[b] - [i] - [u] - [url] - [mail]
function print_texttohtml($text)
{
  $texthtml = null;
  
  $newline = chr(10);   
  $texthtml = preg_replace("#\[b\](.*)\[/b\]#sUi","<b>\\1</b>",$text);
  $texthtml = preg_replace("#\[i\](.*)\[/i\]#sUi","<i>\\1</i>",$texthtml);
  $texthtml = preg_replace("#\[u\](.*)\[/u\]#sUi","<u>\\1</u>",$texthtml);
  $texthtml = ereg_replace($newline,"<br />",$texthtml);
  $texthtml = preg_replace("#\[url(=([^\[\]]*))?\]([^\[\]]*)\[/(url)\]#e", "'<a href=\"' . ('\\2' == '' ? '\\3' : '\\2') . '\" target=\"_blank\">\\3</a>'", $texthtml);
  $texthtml = preg_replace("#\[mail\](.*)\[/mail\]#sUi","<img src=\"render_email.php?gd=\\1\" width=\"195\" height=\"15\" alt=\"\" title=\"\" />", $texthtml);
  return($texthtml);
}
?>


Dit is een UBB script dat ik zelf heb gemaakt en toch al heel lang gebruik. 't Werkt echt wel goed en eigenlijk kan je het fine-tunen zoals je wilt, nog dingen bijvoegen enz enz...

Maar probeer volgende keer toch wat verder te zoeken, moeilijk is het niet.

Bedrijf : Webtrix

Foto materiaal:
Nikon D7100 | Nikor AF-S DX 18-105mm | Nikor AF-S 50mm | Nikon SB600


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
rogierslag schreef op zondag 11 maart 2007 @ 21:01:
Ik heb het uiteindelijk maar gewoon dirty gedaan.

Ik ben er alles behalve tevreden over maar het is beter dan niks
PHP:
1
$output = preg_replace('@>(\040|\t)*(<br \/>|<br>)(\t|\040)*<@', '><', $output);
Erm, je probleem was dat je zowel <br> als <br /> moet vervangen? Dan kun je simpelweg dit gebruiken:
PHP:
1
$output = preg_replace('@>(\040|\t)*(<br[^>]*>)(\t|\040)*<@', '><', $output);


Da's trouwens wel een vrij basic regexp, wellicht inderdaad handiger een bestaande parser te gebruiken?

[ Voor 20% gewijzigd door FragFrog op 11-03-2007 21:45 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • orf
  • Registratie: Augustus 2005
  • Nu online

orf

Dit is een UBB script dat ik zelf heb gemaakt en toch al heel lang gebruik. 't Werkt echt wel goed en eigenlijk kan je het fine-tunen zoals je wilt, nog dingen bijvoegen enz enz...

Maar probeer volgende keer toch wat verder te zoeken, moeilijk is het niet.
Je vergeet dat het probleem waar de TS mee zit niet de ubb code is, maar de combinatie van ubb code. Je wilt niet dit als broncode:

<ul><br />
<li>test</li><br />
</ul><br />

Dat is het gevolg van nl2br. Met preg_replace_callback() kun je dat oplossen door met placeholders te werken. Dit is een voorbeeldje wat ik wel eens geschreven heb:


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
31
32
33
34
35
36
37
38
39
<?php 

function highlight_code($matches){ 
    // in $hl_array worden de highlighted codes tijdelijk opgeslagen 
    global $hl_array; 

    // $hl_num is het nummer die deze code krijgt 
    $hl_num = count($hl_array); 

    // code in array en return van placeholder 
    $hl_array[$hl_num] = highlight_string($matches[1], true); 

    return '{{HL_'.$hl_num.'}}'; 
} 


function encode($message){ 

  global $hl_array; 

  $message = str_replace('{{HL_', '{{ HL_', $message); 
  $message = preg_replace_callback("/\\[CODE\][\n\r]*(.*?)\\[\/CODE\]/is",'highlight_code', $message); 

  $message = htmlspecialchars($message); 
  $message = nl2br($message); 
  $message = preg_replace('#\\[([bisu])\](.*?)\\[/\\1\]#Si', "<$1>$2</$1>", $message); 
    // andere ubb 

  foreach ($hl_array as $hl_num => $code){     

    $message = str_replace('{{HL_'.$hl_num.'}}', $code, $message); 
  } 

  return $message; 

} 


?>


Met [ul] kan dat natuurlijk net zo goed als hier met [code] blokken.
Pagina: 1