Preg_replace - regular expressions matchen niet

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Top Low-Code Developer Gezocht!

Bedrijfsomschrijving Unieke Kansen, Uitstekende Arbeidsvoorwaarden & Inspirerend Team Wij zijn een toonaangevende, internationale organisatie die de toekomst van technologie vormgeeft door het creëren van innovatieve en baanbrekende oplossingen. Ons succes is gebaseerd op een hecht en gepassioneerd team van professionals die altijd streven naar het overtreffen van verwachtingen. Als jij deel wilt uitmaken van een dynamische, vooruitstrevende en inspirerende werkomgeving, dan is dit de perfecte kans voor jou! Functieomschrijving Als Low-Code Developer ben je een cruciaal onderdeel van ons team. Je werkt samen met collega's uit verschillende disciplines om geavanceerde applicaties te ontwikkelen en te optimaliseren met behulp van Low-code

Bekijk vacature »

Robert N

Robert N

04/01/2012 22:31:28
Quote Anchor link
Hi,

Ben ik alweer met een nieuwe vraag over vervangen van teksten :-)
Deze keer is de vraag iets simpeler (denk ik).

Ik heb een paar regels geschreven om zelf gemaakte UBB codes (uit een database) weer om te zetten naar HTML.
Voor links gebruik ik het volgende:

<a title="Google hover" href="www.google.nl/">Klik hier</a>

wordt in mijn UBB;

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
[url=www.google.nl/|Google hover]Klik hier[/url]


(Ook werkt het als er geen title tag is, dan maakt hij van de begin UBB-tag gewoon
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
[url=www.google.nl/]
)


Naar UBB gaat het al super goed, maar de andere kant op nog niet.
Ik gebruik daarin de volgende regels:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
      // link met titel
     $input_toHTML = preg_replace(
        "#\[url=(.+?)\|(.+?)\](.+?)\[/url\]#is",
        "<a title=\"\\2\" href=\"\\1\"\">\\3</a>",
        $input_toHTML);
        
    // link zonder titel
     $input_toHTML = preg_replace(
        "#\[url=(.+?)\](.+?)\[/url\]#is",
        "<a 22 href=\"\\1\">\\2</a>",
        $input_toHTML);
?>


Nu gaan gedeeltes goed. Maar ik heb het idee dat het pattern nog niet klopt.
Kan het zijn dat ik een 'het moet beginnen met' en een 'het moet eindigen met' ben vergeten?
Ik heb de regels deels van internet gehaald en gemodificeerd naar eigen inzicht. Grotendeels snap ik het nu zelf ook!

Wie kan mij hiermee helpen?
Alvast bedankt!
Mvg, Robert

EDIT: Code tussen juiste tags gezet, nu wel leesbaar... ^noob
Gewijzigd op 04/01/2012 23:44:24 door Robert N
 
PHP hulp

PHP hulp

26/04/2024 15:27:41
 
Wouter J

Wouter J

04/01/2012 23:08:19
Quote Anchor link
Voor PHP code moet je <?php voor je code en ?> na je code plaatsen. Voor HTML en JS en CSS en andere code moet je [code] tags gebruiken.
 
- SanThe -

- SanThe -

04/01/2012 23:16:57
Quote Anchor link
En je post ziet er zo vreemd uit doordat je [url=www.google.nl/] in je post hebt staan en dat dus niet afsluit.
Gewijzigd op 04/01/2012 23:17:15 door - SanThe -
 
Robert N

Robert N

04/01/2012 23:44:03
Quote Anchor link
Post aangepast, is nu wel leesbaar.
 
- SanThe -

- SanThe -

05/01/2012 02:47:28
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
$regex
= "#\[url=(.*)\/\|{0,1}(.*?)\](.*)\[/url\]#is";
$replace = "<a title=\"\\2\" href=\"\\1\">\\3</a>";

$input_toHTML = '[url=www.google.nl/|Google hover]Klik hier[/url]';
echo htmlentities(preg_replace($regex, $replace, $input_toHTML));
echo '<br />';
$input_toHTML = '[url=www.google.nl/]Klik hier[/url]';
echo htmlentities(preg_replace($regex, $replace, $input_toHTML));
?>


Voor beiden dezelfde regex geeft dit aan output:

<a title="Google hover" href="www.google.nl">Klik hier</a>
<a title="" href="www.google.nl">Klik hier</a>
 
Robert N

Robert N

05/01/2012 14:05:58
Quote Anchor link
Bedankt voor je antwoord. Ik heb het vervangen. Maar werkt helaas nog steeds niet!
Er zijn een aantal stappen die worden gedaan;

1. Dit is de tekst die in de database staat:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
[p][url=http://www.google.nl]Externe link 1[/url][/p]
[p][url=http://www.phphulp.nl|Goede website]Externe link 2[/url][/p]
[p][url=/systemen]Interne link 1[/url][/p]
[p][url=/systemen/link2|linktekst]Interne link 2[/url][/p]
[p]Groetjes, Test-Kees[/p]



2. Op de nieuwspagina pagina wordt de tekst op deze manier geconverteerd:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
        include 'tekstconversie.php';
        $converted_inhoud = conversie_toHTML($row->inhoud);
?>




3. In tekstconversie.php staat nu (o.a.) het volgende:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
function conversie_toHTML($input_toHTML) {
    $regex = "#\[url=(.*)\/\|{0,1}(.*?)\](.*)\[/url\]#is";
    $replace = "<a title=\"\\2\" href=\"\\1\">\\3</a>";

    $input_toHTML =  preg_replace($regex, $replace, $input_toHTML);

    // input retourneren
    return $input_toHTML;
}

?>



4. Verderop wordt dit alsvolgt gewoon ge-echo'd op het scherm:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
    echo $converted_inhoud;
?>




Maar het resultaat in HTML is toch dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<p><a title="link2|linktekst" href="http://www.google.nl]Externe link 1[/url]</p>
<p>[url=http://www.phphulp.nl|Goede website]Externe link 2[/url]</p>
<p>[url=/systemen]Interne link 1[/url]</p>
<p>=/systemen">Interne link 2</a></p>

<p>Groetjes, Test-Kees</p>


Wat doe ik nog verkeerd?
Het lijkt alsof de regex maar een klein gedeelte vervangt en niet de hele expressie gebruikt. Maar waar gaat het nu fout?
Gewijzigd op 05/01/2012 19:41:38 door Robert N
 
- SanThe -

- SanThe -

05/01/2012 14:18:42
Quote Anchor link
Je geeft nu een compleet andere input. Dat is een heel ander verhaal. Hier zal je toch even moeten wachten op een echte regex-expert.
 
Robert N

Robert N

06/01/2012 11:34:07
Quote Anchor link
Zou een regex expert hier nog even naar willen kijken?
Of moet ik een nieuw topic maken maar dan niet in 'Beginnen met PHP'?

Mvg,
Robert
 
B a s
Beheerder

B a s

06/01/2012 11:46:10
Quote Anchor link
Wijzig die {0,1} eens. Want dat staat voor minimaal 0 en maximaal 1 karakter. Maak daar eens van {0,100}.
Gewijzigd op 06/01/2012 11:46:38 door B a s
 
Jelmer -

Jelmer -

06/01/2012 12:02:44
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
\[url=(.*)\/\|{0,1}(.*?)\](.*)\[/url\]

Die (.*) is greedy, dus alles tussen het begin van de eerste open-tag en einde van de laatste open-tag zal als url gezien worden.
Ook in dat laatste deel, de tekst van de url. Daar kan je .+? gebruiken wat hetzelfde doet als .*, maar dan non-greedy, oftewel die probeert zo weinig karakters als maar mogelijk is te matchen.

Verder gaat die {0,1} (wat je kan schrijven als ?) niet helemaal goed. Zo wel:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
\[url=(.+?)(?:\|(.+?))?\](.+?)\[/url\]

Want (?:xxx)? betekent "match sub-patroon xxx 0 of 1 keer" en xxx is een pipe gevolgd door tekst (weer non-greedy).

Let wel op dat ik nu nog steeds andere dingen dan urls in je tag kan doen waardoor je site er niet veiliger op wordt.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
[url="><script>alert(document.cookie)</script>]an url[/url]

Dat zou je nog kunnen afvangen door je patroon voor urls strikter te maken zodat het alleen echte urls matcht en dit soort dingen niet omzet. Of je maakt gebruik van preg_replace_callback en haalt htmlentities over de url en teksten heen.
 
Robert N

Robert N

06/01/2012 12:31:06
Quote Anchor link
Bas en Jelmer bedankt!

Ik heb nu het volgende:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
$regex
= "#\[url=(.+?)(?:\|(.+?))?\](.+?)\[/url\]#is";
$replace = "<a title=\"\\2\" href=\"\\1\">\\3</a>";
$input_toHTML =  preg_replace($regex, $replace, $input_toHTML);
?>


En het werkt helemaal!

Nog wel een vraagje, wil er natuurlijk wel van leren :-)
Wat is het verschil tussen de (.*) die ik gebruikte, en de (.+?) in het goede script?
Ik snap het 'greedy' nog niet helemaal, kun je een voorbeeldje geven?

Dit is een klein stukje van het script.
De $input_toHTML gaat nog door heel veel andere str_replace heen, o.a. < en > worden weggehaald.
In het begin nog een htmlentries is nog wel een goed idee ja.

Bedankt!
Gewijzigd op 06/01/2012 19:26:15 door Robert N
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.