Tuleeko jo liikaa kyselyjä?
seuraava ongelma ois preg_replacen käytössä.
Koitan muuttaa tekstissä url:ia klikattavaksi linkiksi. Saan sen toki toimimaan mutta haluaisin että se toimii vain jos url ei ole kiinni tekstissä (tämä johtuu taas kerran sekalaisesta lähdedatasta, voi olla jo bbcodea yms)
esim.
blla blaaa http://aa.com toimii
blaa bllaahttp://aa.com ei saa toimia. (näkyy täälläki bugittavan)
sainkin tämän toimimaan mutta jos tekstissä on pelkkä linkki se ei muutu tai linkki on heti rivivaihdon jälkeen niin sekään ei toimi vaikka pitäisi.
Koitin googletella, mutta löytyy vaan noita perus esimerkkejä jossa linkit muutetaan aina riippumatta miten ne tekstissä on
/\bhttp.../
\b on "word break" ja tarkoittaa, että siinä kohtaa alkaa tai loppuu sana. Eli toisella puolella on kirjain ja toisella ei.
Joo, tuo tuomii, mutta koitan yhdistellä eri muutoksia niin mites ne tehdään?
saako tuota käsittelyä mitenkään niin että jos jokin on jo vaihdettu niin siihen ei enään kosketa?
esim
//kuvat automaattisesti html $viesti=preg_replace( '/(?<!src=")(https?:\\/\\/.+(png|jpeg|jpg|gif|bmp))/Ui', '<a href="$1" target=_blank><img src="$1" style="max-width: 700px;" /></a>', $viesti); //linkit ja rivivaihdot automaattisesti $viesti = nl2br(preg_replace( '@( https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '<a href=$1>$1</a>', $viesti));
saa muutenkin kommentoida ja haukkua tätä viritystä. Tämä toimii muuten täydellisesti paitsi linkit ei muutu rivinvaihdon jälkeen
Jos haluat muotoilla vain erilaisia linkkejä, yksinkertaisinta on käyttää funktiota preg_replace_callback, jolloin voit tunnistaa lausekkeessa minkä tahansa linkin ja päättää vasta sen jälkeen, onko se kuva vai muu osoite. Näin vältyt kaikilta usean korvauksen aiheuttamilta ongelmilta. Mutkikkaammatkin korvaukset voi tehdä yhdellä lausekkeella, jolloin samaa osaa tekstistä ei käsitellä moneen kertaan.
Esimerkki:
<?php function korvaa($m) { $html = htmlspecialchars($m[0]); if (!empty($m[1])) { return '<img src="'. $html. '" />'; } if (!empty($m[2])) { return '<a href="'. $html. '">'. $html. '</a>'; } return $html; } $lauseke = array( '(https?://\\S*?\\.(?:png|jpg)(?=\\s|$))', # (?:x) ei numeroi ryhmää '(https?://\\S*?(?=\\s|$))', '[<>&"]' # htmlspecialchars-funktiota varten ); $lauseke = "`". implode("|", $lauseke). "`"; $viesti = "<plaa> http://x/x.png http://x/x.html"; $viesti = preg_replace_callback($lauseke, "korvaa", $viesti); # <plaa> <img src="http://x/x.png" /> <a href="http://x/x.html">http://x/x.html</a>
Tässä esimerkissä jo html muodossa olevat linkit menee rikki
<blockquote>sposti kirjoitti: <b>Katso 2014 Ski-Doo Lineup YouTubessa</b><br><br><p><a href="http://www.youtube.com/watch?v=e1hjYJk4Zh0&feature=youtube_gdata_player">http://www.youtube.com/watch?v=e1hjYJk4Zh0&feature=youtube_gdata_player</a></p></blockquote>
Et voi odottaa kaiken kattavaa ratkaisua, jos et itse edes kerro, mitä kaikkea tekstissäsi on. Miksi ihmeessä siinä on sekaisin HTML:ää ja BBCode-tageja? Jos tämä johtuu jostain aiemmasta korvauksestasi, kehotan lukemaan viestini uudestaan: sanoin, että kannattaa tehdä kaikki korvaukset yhdellä kertaa.
Jos olet ihan varma, että tekstissä oleva HTML-koodi kuuluu sinne, voit lisätä esimerkkiin lausekkeen '(<.*?>)'
, jonka kohdalla palautatkin korvaa-funktiosta tekstin sellaisenaan, sekä tarvittaessa muita vastaavia lausekkeita, jotka ohittavat myös elementtien sisällön, esimerkiksi '(<a\\s.*?>.*?</a>)'
.
Jos on mielestäsi tärkeää, että ennen http:tä pitää olla väli, voit lisätä kyseisten lausekkeiden alkuun tarkistuksen (?<!\\S)
.
Aihe on jo aika vanha, joten et voi enää vastata siihen.