[PHP/regexp] UBB codes met meerdere variables

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • rb338
  • Registratie: Januari 2001
  • Laatst online: 05-01 12:58
Ik probeer een UBB code parser te bouwen die meerdere variables per tag ondersteunt.
De methode die ik als eerste had werkte wel, maar in sommige gevallen niet, dus ben ik opnieuw begonnen.

De volgende 2 voorbeelden moeten mogelijk zijn:
[kolom]hier de tekst[/kolom]
[kolom w=450]hier ook tekst[/kolom]

Ik heb ook tags met 3 opties, bijv. [blok type=1 title=blaat img=bla.gif]tekst in blok[/blok]
Maar dat moet in principe goed te doen zijn als de eerste voorbeelden werken.

Mijn code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function parseCode($text){

   $tagArray['kolom'] = array('open'=>'<td>','close'=>'</td>');
   $tagArray['kolom w=(.*)'] = array('open'=>'<td width="','close'=>'">\\2</td>');

   foreach($tagArray as $tagName=>$replace){
        $tagEnd=preg_replace('/\W/Ui','',$tagName);
        $text = preg_replace("|\\[$tagName\](.*)\\[/$tagEnd\]|si","$replace[open]\\1$replace[close]",$text);
   }
   foreach($sTagArray as $tagName=>$replace){
        $text= preg_replace("|\\[$tagName\]|Ui","$replace[tag]",$text);
   }
   return $text;
}


Die code werkt een beetje. Dat wil zeggen, de [kolom] tag doet het. Echter, de tag met variable niet. Ik verdenk mijn regex ervan dat hij de spatie niet goed opvangt, maar ik kom er echt niet uit. Al diverse regex sites erop nageslagen en ubb parser code bekeken, maar het lukt me echt niet :/

Hoe kan ik dit het beste aanpakken?
Oja, het is geen optie om iets als [kolom=450] te doen, dit ivm de eis van meerdere variabelen...

Acties:
  • 0 Henk 'm!

Verwijderd

Volgens mij komt het omdat je zoals je het nu hebt de tag af moet sluiten met [/kolomw] (vanwege die verdwaalde w die niet gestript wordt).

Acties:
  • 0 Henk 'm!

  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Hmm... over het algemeen zijn regexps niet geschikt voor dit soort parsers... UBB en HTML verschillen niet veel en als je op Perlmonks.org (http://www.perlmonks.org) (goed, geen PHP maar wel regexps een vraag hebt over regexps mbt HTML wordt vaak al snel geantwoord dat ze daar niet geschikt voor zijn.

Is er niet een of andere parser-module die je kan gebruiken?

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


Acties:
  • 0 Henk 'm!

  • rb338
  • Registratie: Januari 2001
  • Laatst online: 05-01 12:58
Hmm daar zeg je wat, dat heb ik helemaal over het hoofd gezien!
Even nakijken...

edit:
UBB-parser module ondersteunt afaik niet meerdere variables :(

edit2:
OneOfBorg: ik heb er eens naar gekeken en nu heb ik het als test even zo gedaan:
PHP:
1
2
$tagArray['email=(.*)'] = array('open'=>'<a href="mailto:','close'=>'">\\2</a>');
$tagArray['kolom=(.*)'] = array('open'=>'<td width="','close'=>'">\\2</td>');

De email tag werkt als ik [email=bla@bla.com]email link[/email] gebruik, maar de kolom tag werkt niet als ik [kolom=400]blah[/kolom] gebruik. Snap het niet :?

[ Voor 91% gewijzigd door rb338 op 12-01-2005 20:10 ]


Acties:
  • 0 Henk 'm!

  • Flying_Thunder
  • Registratie: December 2001
  • Niet online
Deze code
PHP:
1
preg_match("/\\[[\w]+ ([\w*=\w*\.\w* ?]*)]?\](.*)\\[\/\w*\]/i", $string, $matches)

doet wat je vraagt volgens mij, is wel erg ranzig enzo op deze manier maar laat zien dat het wel kan.

In ieder geval lijkt het mij een stuk makkelijker als je eerst al je regexes eens test in een minimaal scriptje en ze daarna pas gebruikt in je parser. Dan weet je iig zeker dat je regexen kloppen en hoef je die niet te debuggen, want er kan wel meer fout zijn als het zaakje niet goed parsed :)

BTW "\W" matched alleen non-word characters he, ik weet niet of dat jouw bedoeling was verder :)

Acties:
  • 0 Henk 'm!

  • rb338
  • Registratie: Januari 2001
  • Laatst online: 05-01 12:58
Ik ben steeds begonnen met een minimaal scriptje :)
Het is sowieso nog niet veel :+

Maar de bedoeling was dat ik bijvoorbeeld dit kan doen:
[blok type=1 title=Dit is een blok img=plaatje.gif]
Dit is de tekst in een blok
[/blok]

Dat ging op zich goed, alleen het probleem was, dat als ik 2x een blok met een img heb hij alles wat tussen de eerste img= en de laatste ] staat pakt als url voor het plaatje (dus ook tussenliggende blokken, etc.) :/

Maar ik ga eens kijken wat ik met jouw regex allemaal kan doen :)

edit:
Krijg 't niet echt voor elkaar.
Word er zo onderhand een beetje gek van 8)7
Toch maar wat anders proberen... mocht er iemand een gouden ingeving krijgen:
graag _/-\o_

[ Voor 19% gewijzigd door rb338 op 12-01-2005 21:39 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

rb338 schreef op woensdag 12 januari 2005 @ 21:02:
Dat ging op zich goed, alleen het probleem was, dat als ik 2x een blok met een img heb hij alles wat tussen de eerste img= en de laatste ] staat pakt als url voor het plaatje (dus ook tussenliggende blokken, etc.) :/
De ungreedy modifier gebruiken ('u' geloof ik). Verder is dit vervelende gedoe met regexps de reden om dit te doen met een tokenizer script. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Flying_Thunder
  • Registratie: December 2001
  • Niet online
Kun je hiermee uit de voeten?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?PHP
$string = '[blok type=1 title=blaat img=bla.gif]tekst in blok[/blok] [blok type=1 title=Dit is een blok img=plaatje.gif]Dit is de tekst in een blok[/blok]';

preg_match_all("/(\\[blok(\s.*?)?\](.*?)\\[\/blok\])/", $string, $matches);

foreach($matches[1] as $key => $value)
{

    $parameters[$key] = $matches[2][$key];
    $content[$key] = $matches[3][$key];
    $replaceregex[$key] = "/".preg_quote($value, "/")."/";

    preg_match_all("/(\w+)=(.*?)(?=\w+=|$)/", $parameters[$key], $matches2);

    foreach ($matches2[1] as $key2 => $tag)
    {
        $tags[$key][$tag] = $matches2[2][$key2];
    }
}
print_r($tags);
print_r($content);

?>


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Array
(
    [0] => Array
        (
            [type] => 1
            [title] => blaat
            [img] => bla.gif
        )

    [1] => Array
        (
            [type] => 1
            [title] => Dit is een blok
            [img] => plaatje.gif
        )

)
Array
(
    [0] => tekst in blok
    [1] => Dit is de tekst in een blok
)

Succes :)

Acties:
  • 0 Henk 'm!

  • rb338
  • Registratie: Januari 2001
  • Laatst online: 05-01 12:58
@Flying_Thunder:
Woei, heel erg bedankt :)
Het kostte nog wat gefriemel ivm het replacen van de blok-tags en het addslashen, maar nu is het gelukt. De code, zodat het topic ook echt een eind heeft ;) :
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
  preg_match_all("/(\\[blok(\s.*?)?\](.*?)\\[\/blok\])/si", $code, $matches);
  foreach($matches[1] as $key => $value) {
    $parameters[$key] = $matches[2][$key];
    $content[$key] = addslashes($matches[3][$key]);
    $replaceregex[$key] = "/".preg_quote($value, "/")."/";
    preg_match_all("/(\w+)=(.*?)(?=\w+=|$)/", $parameters[$key], $matches2);
    foreach ($matches2[1] as $key2 => $tag) {
      $tags[$key][$tag] = $matches2[2][$key2];
    }
  }
  $count = count($tags);

  for ($i = 0; $i < $count; $i++)
     $code = preg_replace("/(\\[blok(\s.*?)?\](.*?)\\[\/blok\])/si", "___blok".$i."___", $code, 1);

  for ($i = 0; $i < $count; $i++) {
    $type = $tags[$i]['type'];
    $title = $tags[$i]['title'];
    $cont = $content[$i];
    $img = $tags[$i]['img'];
    $replace = "/___blok".$i."___/";
    $code = preg_replace($replace, "\<\? drawBox($type,\"$title\",\"$cont\",\"$img\"); \?\>", $code);
  }

  $code = stripslashes($code);

Het is creatief opgelost en het zal niet de schoonheidsprijs verdienen, maar het werkt!

Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
ACM heeft een keer een hele gafe stack-based UBB parser geschreven, misschien kun je daar eens naar kijken. Dat werkt op een hele andere manier.

Acties:
  • 0 Henk 'm!

Verwijderd

Skaah schreef op donderdag 13 januari 2005 @ 16:16:
ACM heeft een keer een hele gafe stack-based UBB parser geschreven, misschien kun je daar eens naar kijken. Dat werkt op een hele andere manier.
oisyn was dat volgens mij, staat op zen website

Acties:
  • 0 Henk 'm!

  • rb338
  • Registratie: Januari 2001
  • Laatst online: 05-01 12:58
Nee was idd ACM, linkje:
http://achelois.tweakers.net/~acm/parse/

Heb er ff naar gekeken maar wat ik nu heb werkt toch makkelijker en snel genoeg ;)

[ Voor 9% gewijzigd door ACM op 09-10-2007 22:40 . Reden: vulcanus.its.tudelft.nl is niet meer ]


Acties:
  • 0 Henk 'm!

  • Flying_Thunder
  • Registratie: December 2001
  • Niet online
Ach, volgens mij wil rb338 zelf een parsert bouwen dus er een lenen van iemand anders is dan niet bepaald leerzaam ;)
BTW is een regexbased parser behoorlijk snel, als je kunt regexen :P
Pagina: 1