[PHP] preg_replace_callback probleem

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Topicstarter
De volgende code gebruik ik nu om [list] tags om te zetten naar HTML.

PHP:
1
2
3
4
5
6
7
8
9
10
$news = preg_replace_callback('/\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list]/is', 'ul', $news);

function ul($matches) {

  $content = $matches[1];
  // toggle nested list
  $content = preg_replace('/\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list]/is',
'<ul>\\1</ul>', $content);
  return '<ul>'.($content).'</ul>';
}


Liep als een trein, alleen 1 probleem. Na de <ul> tags kwam een <br /> tag. Dit vond ik niet mooi dus heb ik geprobeerd om dit op te lossen. Na verschillende zaken geprobeerd te hebben kwam ik uiteindelijk bij Ibex die me het volgende voorstelde:
Ik denk door (\r\n)+? achter [\/list] te zetten, zodat je de volgende reguliere expressie krijgt: /\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is
Natuurlijk moest ik dit ook in de functie toepassen zodat de nieuwe code was:

PHP:
1
2
3
4
5
6
7
8
9
$news = preg_replace_callback('/\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is', 'ul', $news);

function ul($matches) {

  $content = $matches[1];
  // toggle nested list
  $content = preg_replace('/\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is', '<ul>\\1</ul>', $content);
  return '<ul>'.($content).'</ul>';
}



Ok, dat werkte dus. De <br /> tag na de </ul> was weg. Vervolgens wou ik ook de <br /> tag na de <ul> weghalen.
/\[list](\r\n)+?((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is
De nieuwe code werd vervolgens:


PHP:
1
2
3
4
5
6
7
8
9
$news = preg_replace_callback('/\[list](\r\n)+?((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is', 'ul', $news);

function ul($matches) {

  $content = $matches[1];
  // toggle nested list
  $content = preg_replace('/\[list](\r\n)+?((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is', '<ul>\\1</ul>', $content);
  return '<ul>'.($content).'</ul>';
}


maar dit werkt dus niet.

Ik kom er niet meer uit. Ik staar me er al 4 uur blind op in totaal.

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 21:18

crisp

Devver

Pixelated

kan je niet gewoon:
PHP:
1
  return '<ul>'.trim($content).'</ul>';

doen? Of dat trimmen ook met een callback regelen?
Ik meen me overigens te herinneren dat de originele opzet van deze constructie iets anders was; in de functie doe ik namelijk ook een callback volgens mij.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Topicstarter
crisp schreef op 13 juli 2004 @ 11:03:
kan je niet gewoon:
PHP:
1
  return '<ul>'.trim($content).'</ul>';

doen? Of dat trimmen ook met een callback regelen?
Ik meen me overigens te herinneren dat de originele opzet van deze constructie iets anders was; in de functie doe ik namelijk ook een callback volgens mij.
Klopt, de originele functie die je me gegeven hebt destijds had te maken met inline quote tags. Deze gebruik ik nu ook om inline lists af te vangen.

Ik was in de veronderstelling dat trim alleen bedoeld was om leading en trailing spaces te verwijderen. Een blik in de PHP manual leert me dat het niet het geval is.

:o Toch maar iets minder in VB doen :P

Ok, het werkt (was te verwachten).

Maar nu krijg ik nog ongewenste <br /> na </li>

PHP:
1
$news = preg_replace("#\\[li\](.*?)\\[/li\]#si", "<li>\\1</li>", $news);


een (\r\n)+? toevoegen gaat niet werken omdat de \r\n al in een eerder stadium gestript worden. Ik zou ook hier graag \\1 willen trimmen.

Maar op basis van die reguliere expressie kan ik geen call-back maken.

offtopic:
Het valt me wel op dat jij altijd in mijn topics te vinden bent hier in PW ;)

[ Voor 15% gewijzigd door Schonhose op 13-07-2004 12:09 ]

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 21:18

crisp

Devver

Pixelated

waarom kan je daar geen trim gebruiken mbv een callback?

PHP:
1
2
3
4
5
$news = preg_replace_callback('/\\[li\](.*?)\\[\/li\]/is', 'trimli', $news);

function trimli($matches) {
  return '<li>'.trim($matches[1]).'</li>';
}


maar waarschijnlijk zit je met het probleem dat een newline tussen [ /li ] en [ li ] een <br /> wordt?

[ Voor 8% gewijzigd door crisp op 13-07-2004 12:01 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Het is natuurlijk wel het mooiste om alles in 1 keer op te lossen .. maar je kan natuurlijk ook 2 bewerkingen doen.

1e: newlines enzo eruit
2e: wat je al doet

Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Topicstarter
ja das inderdaad het probleem.

De input:
code:
1
2
3
4
[list]
[*]item 1
[*]item 2
[/list]


Middels een PreParse worden de [*] omgezet in [li] tags:
PHP:
1
$news = preg_replace("/\\[\*\]([^\r\n]*)/i", "[li]\\1[/li]", $news);


Aanname is dat er altijd een newline is na [*]

dan heb ik:
code:
1
2
3
4
[list]
[li]item 1[/li]
[li]item 2[/li]
[/list]


en dat levert me ook met jouw bovenstaande oplossing:
HTML:
1
2
<ul><li>item 1</li><br />
<li>item 2</li></ul><br />


en de laatste <br /> op regel 1 is nu het probleem.

@Joozt: de newlines moeten er wel inzitten anders krijg ik alle tekst op 1 bericht. Ik moet dan alleen de newlines slopen uit het gedeelte wat tussen de <ul> zit

[ Voor 20% gewijzigd door Schonhose op 13-07-2004 12:20 ]

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 21:18

crisp

Devver

Pixelated

Schonhose schreef op 13 juli 2004 @ 12:19:
[...]
Middels een PreParse worden de [*] omgezet in [li] tags:
PHP:
1
$news = preg_replace("/\\[\*\]([^\r\n]*)/i", "[li]\\1[/li]", $news);


Aanname is dat er altijd een newline is na [*]
[...]
En precies op dit punt zal je de newlines eruit moeten slopen om je probleem op te lossen.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Topicstarter
met

PHP:
1
$news = preg_replace("/\\[\*\](.*?)\r\n*/si", "[li]\\1[/li]", $news);


werkt ie. \o/

Dan waren er nog wat problemen met een <br /> na de </ul> tag. Dit heb ik opgelost in de desbetreffende preg_replace (\r\n)+? achter [\/list] te zetten (zie ook mijn eerste post.

Nu werkt het.

[ Voor 53% gewijzigd door Schonhose op 13-07-2004 13:28 ]

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 21:18

crisp

Devver

Pixelated

persoonlijk zou ik gewoon alle whitespace strippen, en niet alleen de windows-sequence van een enter:
PHP:
1
$news = preg_replace('/\\[\*\]([^\r\n]*)\s*/is', '[li]$1[/li]', $news);

[ Voor 3% gewijzigd door crisp op 13-07-2004 13:33 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Topicstarter
ok, maar ik zie net nog een bug.

In mijn vorige post schreef ik dat ik last had van een <br /> na een </ul> deze heb ik vervangen met:

PHP:
1
2
3
4
5
6
7
8
9
$news = preg_replace_callback('/\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is', 'ul', $news);

function ul($matches) {

  $content = $matches[1];
  // toggle nested list
  $content = preg_replace('/\[list]((([^[]|\\[(?!\/?list))*|(?R))*)\\[\/list](\r\n)+?/is', '<ul>\\1</ul>', $content);
  return '<ul>'.($content).'</ul>';
}


Maar wanneer er geen enter wordt gegeven naar de [/list] worden de tags niet vervangen.

Hoe kan ik dat oplossen zodat ie een replace doet wanneer er geen of juist wel een enter wordt gegeven?

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

Verwijderd

door eerst je input te normaliseren

probeer eerst iets te maken in de vorm:

code:
1
[list][li]item 1[/li][li]item 2[/li][/list]


en dan je andere regex
dat bedoelde ik met 2 stappen :)

gl

Acties:
  • 0 Henk 'm!

  • Schonhose
  • Registratie: April 2000
  • Laatst online: 17-09 20:01

Schonhose

Retro Icoon

Topicstarter
Verwijderd schreef op 13 juli 2004 @ 13:53:
door eerst je input te normaliseren

probeer eerst iets te maken in de vorm:

code:
1
[list][li]item 1[/li][li]item 2[/li][/list]


en dan je andere regex
dat bedoelde ik met 2 stappen :)
Dat heb ik gedaan en het werkt inderdaad. Ik betwijfel of het efficient is hoe ik het nu doe, maar ik ben van mijn probleem af. :)

"The thing under my bed waiting to grab my ankle isn't real. I know that, and I also know that if I'm careful to keep my foot under the covers, it will never be able to grab my ankle." - Stephen King
Quinta: 3 januari 2005


Acties:
  • 0 Henk 'm!

  • Ibex
  • Registratie: November 2002
  • Laatst online: 21:02

Ibex

^^ met stom.

Bij de laatste code de \\1 vervangen door \\2. Dat zou moeten werken :)

Archlinux - Rode gronddingetjes zijn lekker - Komt uit .be

Pagina: 1