[PHP/UBB] Krijg recursieve regex niet goed

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer een functie te schrijven die een geneste div met als attribuut een class, goed omzet naar html:

PHP:
1
2
3
4
5
6
7
function create_div($input) {
    $regex = '#\[div=([a-z0-9\#\?\.&/]*)\]((?:[^[]|\[(?!/?div])|(?R))+)\[/div]#';
    if (is_array($input)) {
        $input = '<div class="'. $input[1] .'">'. $input[2] .'</div>';
    }
    return preg_replace_callback($regex, 'create_div', $input);
}

Het idee is dus om deze input:
code:
1
2
3
4
[div]
  [div=left]dsadsadsadasdsa[/div]
  [div=right]dsadasdsadasds[/div]
[/div]

om te zetten naar
code:
1
2
3
4
<div>
  <div class="left">dsadsadsadasdsa</div>
  <div class="right">dsadasdsadasds</div>
</div>

Waarom werkt mijn code niet? Voor zover ik het snap, controleer de regex op 2 matches: div en class?

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Kan je dan niet beter gaan tokenizen?

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 18-09 10:39
Als ik 'm invul op www.regular-expressions.info/javascriptexample.html krijg ik in elk geval vanuit FireBug de melding:
Invalid quantifier ?R))+)\[\/div]#
[Break on this error] var re = new RegExp(document.demoMatch.regex.value)

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Ik kom hierop uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function create_div($input)
{
    $regex = '#\[div(=([a-z0-9\#?.&/]*))?]((([^[]*|\[(?!/?div))*|(?R))*)\[/div]#';

    if (is_array($input))
    {
        $result = '<div' . ($input[2] ? ' class="'. $input[2] . '"' : '') . '>'
                . preg_replace_callback($regex, 'create_div', $input[3])
                . '</div>';
    }
    else
    {
        $result = preg_replace_callback($regex, 'create_div', $input);
    }

    return $result;
}


maar je kan beter naar BtM909 luisteren, dit soort constructies is vragen om problemen ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Lees vooral ook even [PHP / UBB] Wat is nu het voordeel van stack-based parsen? door waarom dat vragen om problemen is. :)

'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!

Verwijderd

Topicstarter
Ik heb inmiddels redelijk wat gelezen over stackbased parsen en er ook wat voorbeelden bijgehaald. Het nadeel is alleen dat ik het moeilijk te begrijpen vind; in ieder geval moeilijker dan wat regex'en onder elkaar zetten (hoe ranzig dat ook niet is).

Ik vraag me bovendien af of een stackbased parser soms geen overkill is: ik wil dat gebruikers bij mij een b, u, i, p, img, url en div-tag kunnen gebruiken, waarbij de div-tags genest kunnen zijn. Volgens mij is dat redelijk bullet proof te krijgen met wat regexen. Ik begrijp dat het voordeel van stackbased is dat je de context van een tag binnen het geheel van tags kunt bepalen, en ik zie dat dat nodig is als je zaken als geneste tabellen en geneste lists gaat toestaan. Maar dat zijn features die ik toch niet wil inbouwen in mijn cms, dus volgens mij weegt het voordeel van stackbased in dat geval niet op tegen de (vele) uren die ik zou moeten steken in het ontwikkelen ervan?

@crisp - bedankt, dit werkt perfect :) Ik ga kijken wat je precies gedaan hebt.

[ Voor 3% gewijzigd door Verwijderd op 03-08-2007 12:47 ]


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Wat doe je als iemand een div-tag gebruikt binnen een bold-tag? Wat doe je als iemand tags in een verkeerde volgorde afsluit? En belangrijker: wat als blijkt dat crisp's regexp toch niet helemaal voldoet en je moet hem over een jaar aanpassen...lijkt je dat eenvoudig? ;)

Stackbased parsen is niet complex en geen overkill. Het is een handige tool om er zeker van te zijn dat zaken als nesting gewoon werken, en dat alles binnen een bepaalde context klopt zodat je ook valide HTML uitpoept. <b>blaat<div>foobar</div></b> is bijvoorbeeld al niet netjes. ;)

'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!

Verwijderd

Topicstarter
@ -NMe- dat klinkt logisch, maar toch is het zo dat zelfs oisyn's parser van
code:
1
[b][quote=http://nu.nl,bron]Quote met bronvermelding[/][/b]

dit maakt
code:
1
<b><div class="quoteouter">quote: <a href="http://nu.nl" target="_blank">bron</a><div class="quoteinner">Quote met bronvermelding</div></div></b>

Met andere woorden, de b-tags omvatting de quote-div, ipv dat ze erbinnen gezet worden (als dat is wat je bedoelt). Hoe zou een parser de logische volgorder van de tags moeten bepalen? Dan moet je toch een hele grammatica definieren?

[ Voor 10% gewijzigd door Verwijderd op 03-08-2007 13:08 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

zecco: dat heeft geen zak met mijn parser te maken, maar met de logica die de syntax tree gebruikt om de html van te bouwen. Een <div> binnen een <b> mag idd niet, maar daar had ik simpelweg gewoon geen rekening mee gehouden :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@oisyn - is dat dan iets wat in de settings file van jouw parser bijvoorbeeld is aan te passen of heeft het met iets anders te maken? Waar wordt die syntax tree gedefinieerd? En is die aan te passen? Het lijkt me toch bijna niet te doen om alle "foute" nestingen van tags te definieren: een div mag immers niet binnen een b, u, i, table, tr, td, etc. maar weer wel binnen een andere div. En zo zullen er nog wel een hoop regels te verzinnen zijn (table niet binnen b, u, i, etc., script tag niet binnen een b, u, i etc.)

En is het de taak van een parser om van
code:
1
[b][u]dit is tekst[/b][/u]

dit te maken?
code:
1
<b><u>dit is tekst</u></b>

[ Voor 54% gewijzigd door Verwijderd op 03-08-2007 13:26 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Verwijderd schreef op vrijdag 03 augustus 2007 @ 13:22:
@oisyn - is dat dan iets wat in de settings file van jouw parser bijvoorbeeld is aan te passen of heeft het met iets anders te maken? Waar wordt die syntax tree gedefinieerd? En is die aan te passen? Het lijkt me toch bijna niet te doen om alle "foute" nestingen van tags te definieren: een div mag immers niet binnen een b, u, i, table, tr, td, etc. maar weer wel binnen een andere div. En zo zullen er nog wel een hoop regels te verzinnen zijn (table niet binnen b, u, i, etc., script tag niet binnen een b, u, i etc.)
Inderdaad, als je UBB als een subset van HTML ziet dan zou de perfecte UBB parser eigenlijk een HTML-parser moeten zijn die context-aware is.

Ik ben het dan ook niet eens met de stelling dat een goede stackbased parser niet complex is en makkelijk te maken.
En is het de taak van een parser om van
code:
1
[b][u]dit is tekst[/b][/u]

dit te maken?
code:
1
<b><u>dit is tekst</u></b>
Dat is een eigen keuze die je maakt bij het bouwen van een parser: in hoeverre wil je error-correctie doen en op welke manier? Ook dat is niet eenvoudig.

Kortom: ik kan me eigenlijk best goed voorstellen dat je uiteindelijk toch kiest voor een oplossing mbv reguliere expressies. Een andere eenvoudige oplossing is gebruik maken van een parser die al door een ander gebouwd is ;)

[ Voor 8% gewijzigd door crisp op 03-08-2007 13:39 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022

Reveller

Hopla!

crisp schreef op vrijdag 03 augustus 2007 @ 13:37:
[...]
Kortom: ik kan me eigenlijk best goed voorstellen dat je uiteindelijk toch kiest voor een oplossing mbv reguliere expressies. Een andere eenvoudige oplossing is gebruik maken van een parser die al door een ander gebouwd is ;)
Ik ben het ermee eens dat het niet fijn is om na een jaar nog oude reguliere expressies te moeten tweaken, omdat het vaak stevig inlezen is in wat er nu eigenlijk gebeurt. Maar met wat goede manuals ernaast is dat voor mij te doen. Een parser gebruiken die al door een ander gebouwd is, is geen optie. Ik heb mijn cms zelf geschreven en wil er geen "foreign" code in hangen, helemaal niet als ik deze eigenlijk niet begrijp. Dan is de lol er voor mij af :)

Ik zie echt wel voordelen van een stackbased parser in, maar naar mijn mening moet je die voordelen dan ook geheel uitbuiten, bijvoorbeeld door hem geheel context-aware te maken. Voor mijn projectje voldoet een "parser" mbv reguliere expressies op dit moment voldoende. Wel ga ik proberen om ook die dan wel zo bulletproof mogelijk te maken :)

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

crisp schreef op vrijdag 03 augustus 2007 @ 13:37:
Ik ben het dan ook niet eens met de stelling dat een goede stackbased parser niet complex is en makkelijk te maken.
Dat laat natuurlijk niet onverlet dat een voldoende stackbased parser dat wél kan zijn. :) In dat geval ga je natuurlijk wel steeds dichter naar de functionaliteit die je ook met regexps kan behalen, maar zoals eerder aangehaald in dit topic is ook onderhoudbaarheid en performance van belang, en niet alleen functionaliteit. :)

'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!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

-NMe- schreef op vrijdag 03 augustus 2007 @ 14:15:
[...]

Dat laat natuurlijk niet onverlet dat een voldoende stackbased parser dat wél kan zijn. :) In dat geval ga je natuurlijk wel steeds dichter naar de functionaliteit die je ook met regexps kan behalen, maar zoals eerder aangehaald in dit topic is ook onderhoudbaarheid en performance van belang, en niet alleen functionaliteit. :)
True, het tokenizen zelf is geen rocket-science (daar kan je overigens prima reguliere expressies voor gebruiken ;)) en daarmee ben je eigenlijk al een heel eind. Met een simpele stack bereik je dan al snel de functionaliteit die je met reguliere expressies ook al had (en beter zelfs).

Uiteindelijk kan je daar dan weer zaken aan toevoegen zoals configuratie, context-awareness en error-correctie. Vooral de laatste twee maken het eigenlijk pas complex.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op vrijdag 03 augustus 2007 @ 13:22:
@oisyn - is dat dan iets wat in de settings file van jouw parser bijvoorbeeld is aan te passen of heeft het met iets anders te maken? Waar wordt die syntax tree gedefinieerd?
Een parser genereert een syntax tree. Dat is ook eigenlijk alles wat een parser doet. Het woord "parser" wordt veel teveel gebruikt voor dingen die helemaal niets met parsen te maken hebben, zoals het uitvoeren van script code of het omzetten van ubb naar html code. Een parser doet niets meer dan het transformeren van input naar een abstracte syntax tree, gegeven een grammatica.

Ik weet niet welke versie jij hebt, maar m'n meest recente versie (ook alweer een paar jaar oud hoor ;), maar ik weet niet of ik die versie ooit online hebt gezet) retourneert gewoon een syntax tree als je oml_parse() aanroept. Die syntax tree kun je vervolgens weer op de oude manier processen door oml_process() aan te roepen met de settings tabel, maar je kunt er ook zelf doorheen bladeren.

Als je niet wilt dat een quote in een b kan, dan zul je de quote moeten negeren op het moment dat je in een b zit.
Het lijkt me toch bijna niet te doen om alle "foute" nestingen van tags te definieren: een div mag immers niet binnen een b, u, i, table, tr, td, etc. maar weer wel binnen een andere div. En zo zullen er nog wel een hoop regels te verzinnen zijn (table niet binnen b, u, i, etc., script tag niet binnen een b, u, i etc.)
Je moet dingen categorizeren, want eigenlijk is het heel simpel. list, table, div, etc. vallen allemaal binnen de categorie "block-tags" (daar is vast een officiele naam voor maar ik ken de terminologie niet), en dingen als b, u, i, etc. vallen binnen de categorie "span-tags". Een block-tag mag in een andere block-tag, maar niet in een span-tag. Een span-tag mag in principe overal in. En verder zijn er nog wat custom regeltjes, zoals dat een tr (en alleen een tr) alleen in een table mag, en een td alleen in een tr, maar dat is vrij makkelijk te definieren.
En is het de taak van een parser om van
code:
1
[b][u]dit is tekst[/b][/u]

dit te maken?
code:
1
<b><u>dit is tekst</u></b>
Nee dus, zie de eerste alinea van mijn post :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

.oisyn schreef op vrijdag 03 augustus 2007 @ 14:43:
[...]

Een parser genereert een syntax tree. Dat is ook eigenlijk alles wat een parser doet. Het woord "parser" wordt veel teveel gebruikt voor dingen die helemaal niets met parsen te maken hebben, zoals het uitvoeren van script code of het omzetten van ubb naar html code. Een parser doet niets meer dan het transformeren van input naar een abstracte syntax tree, gegeven een grammatica.
True, het parsing proces omvat tokenisation en treebuilding, alles daarna zou je 'rendering' kunnen noemen.
[...]
Je moet dingen categorizeren, want eigenlijk is het heel simpel. list, table, div, etc. vallen allemaal binnen de categorie "block-tags" (daar is vast een officiele naam voor maar ik ken de terminologie niet), en dingen als b, u, i, etc. vallen binnen de categorie "span-tags". Een block-tag mag in een andere block-tag, maar niet in een span-tag. Een span-tag mag in principe overal in. En verder zijn er nog wat custom regeltjes, zoals dat een tr (en alleen een tr) alleen in een table mag, en een td alleen in een tr, maar dat is vrij makkelijk te definieren.
Blocklevel elements versus inline. Tabellen zijn eigenlijk geen van beide maar zou je als blocklevel kunnen behandelen. Daarbij hebben veel elementen in HTML eigen parsing constraints en regels en bepalen ze het contentmodel van de inhoud (CDATA, PCDATA, RCDATA, PLAINTEXT). HTML gaat zelfs nog veel verder: empty elements, optional tags en implicit elements en regels zoals: een <table> moet tenminste 1 <tr> bevatten, en een <tr> moet tenminste 1 <td> of <th> bevatten. Of je zo ver zou willen gaan in een UBB parser is echter maar de vraag ;)
[...]

Nee dus, zie de eerste alinea van mijn post :)
Toch wel, error-correctie zal je wel in de parser moeten doen. Syntax-errors zal je in de tokeniser moeten afvangen en tagmatching doe je in de treebuilder, dus zal je daar ook je mismatched tags moeten corrigeren (of negeren of afkappen en een YSOD met een vage foutmelding aan de gebruiker presenteren :P)..

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

.edit: dubbel

[ Voor 82% gewijzigd door .oisyn op 03-08-2007 15:04 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

Toch niet, ik zie daar html output, een parser genereert geen html output :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • ATS
  • Registratie: September 2001
  • Laatst online: 18-09 15:14

ATS

Ik zie de HTML niet in het verheel van crisp? Hij zegt alleen dat je een errors moet afvangen in de parser en dat je tagmatching moet doen in je treebuilder. Daar komt toch nog geen HTLM bij kijken? Het stuk code wat dit aanstuurt en een error terug krijgt zal verantwoordelijk zijn om dat (in HTML, I guess) te presenteren aan de gebruiker lijkt me.

My opinions may have changed, but not the fact that I am right. -- Ashleigh Brilliant


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

.oisyn schreef op vrijdag 03 augustus 2007 @ 15:04:
[...]

Toch niet, ik zie daar html output, een parser genereert geen html output :)
pfft, je begrijpt toch wel wat zecco bedoelt? ;)

Maar goed dan: het is de taak van de parser om een correcte tree te genereren, al dan niet met toegepaste error-correctie.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

.oisyn schreef op vrijdag 03 augustus 2007 @ 15:04:
[...]

Toch niet, ik zie daar html output, een parser genereert geen html output :)
De errors hoeven niet direct HTML output te zijn, maar je zou ze eventueel door kunnen geven in een ander formaat om ze door te sturen naar het gedeelte dat er HTML van gaat maken. Deze zou de errors moeten verwerken.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

ATS schreef op vrijdag 03 augustus 2007 @ 15:17:
Ik zie de HTML niet in het verheel van crisp? Hij zegt alleen dat je een errors moet afvangen in de parser en dat je tagmatching moet doen in je treebuilder. Daar komt toch nog geen HTLM bij kijken? Het stuk code wat dit aanstuurt en een error terug krijgt zal verantwoordelijk zijn om dat (in HTML, I guess) te presenteren aan de gebruiker lijkt me.
Als het uiteindelijke doel van je parser is om een tree te genereren die door een renderengine eenvoudig omgezet kan worden naar geserialiseerde HTML dan is het prettig als de tree al voldoet aan de conformance requirements van HTML. Dat maakt de renderer relatief eenvoudig (en je parser behoorlijk specifiek :P)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

kokx schreef op vrijdag 03 augustus 2007 @ 15:21:
[...]

De errors hoeven niet direct HTML output te zijn, maar je zou ze eventueel door kunnen geven in een ander formaat om ze door te sturen naar het gedeelte dat er HTML van gaat maken. Deze zou de errors moeten verwerken.
ATS schreef op vrijdag 03 augustus 2007 @ 15:17:
Ik zie de HTML niet in het verheel van crisp? Hij zegt alleen dat je een errors moet afvangen in de parser en dat je tagmatching moet doen in je treebuilder. Daar komt toch nog geen HTLM bij kijken? Het stuk code wat dit aanstuurt en een error terug krijgt zal verantwoordelijk zijn om dat (in HTML, I guess) te presenteren aan de gebruiker lijkt me.
Jullie hebben het beide over compleet andere dingen die niets met deze draad te maken hebben. Het gaat helemaal niet om foutmeldingen die aan de gebruiker gegeven worden. Het gaat erom dat een parser om moet kunnen gaan met foute invoer, en daar eventueel correctie op toepast. Een parser output geen html maar een syntax tree, hence het is niet de taak van een parser om "[b]aap[/b]" om te zetten in "<b>aap</b>".

Een parser moet foutieve invoer als "[b]aap[i]noot[/b]mies[/i]" echter wel kunnen snappen op een of andere manier. Of de parser ook verantwoordelijk is voor het corrigeren van fouten zou ik niet glashard willen stellen. Je zou ook kunnen zeggen dat de parser een superset van mogelijke invoer accepteert, en dat je daarna een semantic analyser over de syntax tree heenhaalt om de semantische fouten eruit te halen, zoals je dat bij programmeertalen ook ziet. Daarom ben ik het niet eens met de stelling "het is de taak van een parser om fouten te corrigeren" - het kan, maar het hoeft niet.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022

Reveller

Hopla!

Voel me bijna bezwaard om na zo'n heftige discussie met een vraag van mijn niveau te komen maar ik doe het toch ;)

Om de [email]-tag af te vangen gebruik ik twee reguliere expressies:
code:
1
2
'/\[email\](.+?)\[\/email\]/is' => '<a href="mailto:$1">$1</a>',
'/\[email=(.+?)\](.+?)\[\/email\]/is' => '<a href="mailto:$1">$2</a>',

Zoals je ziet controleer ik eerst op een lege tag ([email]me@site.com[/email]) en daarna op een uitgebreidere ([email=me@site.com]mail dirk[/email])

Hoe kan ik deze twee afvangen in 1 regex?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Reveller schreef op vrijdag 03 augustus 2007 @ 19:51:
Voel me bijna bezwaard om na zo'n heftige discussie met een vraag van mijn niveau te komen maar ik doe het toch ;)

Om de [email]-tag af te vangen gebruik ik twee reguliere expressies:
[...]

Hoe kan ik deze twee afvangen in 1 regex?
something like this:
PHP:
1
2
3
4
5
$input = preg_replace(
    '/\[email(=([^]]+))?](.+?)\[\/email]/ise',
    '\'<a href="mailto:\'.(\'$1\'?\'$2\':\'$3\').\'">$3</a>\'',
    $input
);

maar echt overzichtelijker wordt het er niet op. Een callback zou dan misschien nog beter zijn, of gewoon toch maar 2 losse expressies ;)

Intentionally left blank

Pagina: 1