Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: wyrażenie regularne - linki pod sobą
Forum PHP.pl > Forum > PHP
nospor
Mam taki kod:
  1. $m="http://test.pl\nhttp://test.pl\nhttp://test.pl\nhttp://test.pl";
  2. $search = array (
  3. '#([^/]|^)(www\..*?\..*?)(\s|$)#si',
  4. '#([^">]|^)(https?://.*?\..*?)(\s|$)#si'
  5. );
  6. $replace = array(
  7. '\\1<a href="http://\\2">\\2</a>\\3',
  8. '\\1<a href="\\2">\\2</a>\\3'
  9. );
  10. $m = preg_replace($search, $replace, $m);
  11. $m = nl2br($m);
  12. echo $m;

Jego zadaniem jest zamiant tekstów linkowych na pełne linki w kodzie html. Jednak gdy teksty linkowe oddzielone są od siebie \n to na linki zamienia mi co drugi link tekstowy. Gdyby były oddzielone \r\n tp by zamieniał wszystkie na linki.
W czym problem? Nie chcę tego obchodzić na zasadzie podmianiania \n na \r\n. Chciałbym to załatwić przez właściwe wyrażenie regularne.
Uriziel01
Hmmmm, jest tutaj jakiś szczególny haczyk ? Nie jestem zbyt mocny w wyr. regularnych ale to wydaje mi się dosyć proste.
Można by na przykład tak ? :
  1. $m="http://test.pl\nhttps://test.pl\nhttp://test.pl\nhttp://test.pl\nhttps://test.com\nhttp://test.pl";
  2. $wynik = preg_replace("#(https?://|www.)(.*)([\n]|)#i","<a href=\"$1$2\">$2</a>\n",$m);
  3. $wynik = nl2br($wynik);
  4. var_dump ($wynik);
  5. echo $wynik;


Oczywiście popraw mnie jeżeli piszę kompletne głupoty, ot tylko taki mój mały pomysł. smile.gif
nospor
Nie, nie ma haczyka, poprostu nie działa smile.gif
Twój sposób działa dla tego przypadku.
A jesteś w stanie powiedzieć co w moim wyrażeniu jest nie tak, że nie działa?

Początek mojego wyrażenia, czyli o to: ([^">]|^) psuje wszystko. Twoje działa bo nie ma tego początku smile.gif
No ale ja ten początek muszę mieć. Idzie to jakoś poprawić?
Uriziel01
Tzn. można zrobić z tego ([^">]|) i pozornie działa ale to zależy do czego ci jest to konkretnie potrzebne, bo wcześniej tam była reguła 'lub nie puste' a teraz jest 'lub puste'. Może lepiej pokaż jakiś większy przykład na którym będzie można się oprzeć.
zegarek84
Cytat(nospor @ 27.01.2012, 18:37:59 ) *
A jesteś w stanie powiedzieć co w moim wyrażeniu jest nie tak, że nie działa?

co drugie masz, gdyż na końcu wyrażenie dopasowywało Ci się do białego znaku, tam było kończone wyszukiwanie i za tym białym znakiem rozpoczynana była następna próba dopasowania - a ponieważ nie było już białego znaku (innego znaku niż w pierwszym warunku) próbowało się dopasować do pustych znaków na początku, które nie były puste, gdyż już jest tekst na początku...

moja propozycja która wstępnie działa:
  1. $m="http://test.pl\nhttp://test.pl\nhttp://test.pl\nhttp://test.pl";
  2. $search = array (
  3. '#([^/]|^)(www\.[^\s]+\.[^\s]{2,5})#si',
  4. '#([^">\']|^)(https?://[^\s]+\.[^\s]{2,5})#si'
  5. );
  6. $replace = array(
  7. '\\1<a href="http://\\2">\\2</a>',
  8. '\\1<a href="\\2">\\2</a>'
  9. );
  10. $m = preg_replace($search, $replace, $m);
  11. $m = nl2br($m);
  12. echo $m;

propozycja Uriziel01 bez modyfikatora s też powinna działać po dodaniu na początku ([^">\']|^) - oczywiście cyferki się zmienią - ale mi się sprawdzać nie chce
po za tym nie lepiej skorzystać z callbacka przy zamianie bardziej złożonego ciągu?? - można wtedy dorzucić kilka ekstra sprawdzeń...
by_ikar
Też uważam że lepiej to zrobić callbackiem, i działający przykład dałem tutaj: http://forum.php.pl/index.php?showtopic=18...t-member-912891

Ale również można całość machnąć w jednym wyrażeniu, używając negatywnego przewidywania wstecznego i takie wyrażenie wyglądać będzie w ten sposób:

Kod
#(?<!["'>]) ((f|ht)tp(s)?://[^\s]+)#is


A działać będzie w taki sposób: http://gskinner.com/RegExr/?2vrhs Oczywiście wyrażenie do przechwytywania linków dostosujesz już pod swoje wymagania, osobiście używam takiego, ponieważ często w tekście można napisać www dodając kropkę i powstają niepotrzebnie linki wink.gif

BTW w przypadku kiedy będziesz szukać linków również po www, to moja metoda jak i wszystkich innych którzy tutaj podali jakieś rozwiązanie, będzie działać nieprawidłowo. Z prostego względu, kiedy szukasz linków po www, a wykluczasz jedynie apostrof/cudzysłów, wówczas mając w kodzie html link zaczynający się od http, taki link również zostanie złapany. Czyli prócz samego wykluczania apostrofu/cudzysłowia, musiałbyś jeszcze wykluczyć ftp/http/https i pewnie jeszcze kilka innych protokołów. Dlatego lepiej wyszukiwanie linku po www sobie darować wink.gif chyba że ci na tym zależy, to trzeba by wówczas pokombinować.. wink.gif

EDIT: małe poprawki w wyrażeniu, zapomniałem o spacji i łapało za dużo.. Ogólnie to widzę że to i tak nie jest idealne rozwiązanie i będzie trzeba trochę pokombinować żeby to jakoś działało. Jednak lepszy callback wink.gif
kukix
Cytat(Uriziel01 @ 27.01.2012, 19:24:01 ) *
Hmmmm, jest tutaj jakiś szczególny haczyk ? Nie jestem zbyt mocny w wyr. regularnych ale to wydaje mi się dosyć proste.
Można by na przykład tak ? :



Spróbuj sobie na przykładzie adresu bez http:// taki odnosnik źle działa.. trzeba wtedy dokleić http://
Uriziel01
Cytat(kukix @ 27.01.2012, 21:51:20 ) *
Spróbuj sobie na przykładzie adresu bez http:// taki odnosnik źle działa.. trzeba wtedy dokleić http://

Hmmm, a jak mając samo test.pl masz zamiar powiedzeć że to linka ? Przecież mogę napisać w poście 'słowo.Tak więc' całkowicie przypadkowo nie chcąc aby zostało to zamienione na jakikolwiek link w stylu <a href="http://slowo.tak">/slowo.tak</a>, tak więc bez http,https,ftp,www nie jest to adres a jedynie zwykła fraza.
nospor
Ok, dziękuję panowie. W wolnej chwili przeanalizuje to wszystko na spokojnie smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.