Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][Regex]
Forum PHP.pl > Forum > Przedszkole
maviozo
Wyrażenia regularne niestety chyba nigdy nie będą moją specjalnością i wykładam sie przy prostych czynnościach. niby to rozumiem, ale nie wychodzi i już. Jest proste wyrażenie:
  1. `((?:https?|ftp)://\S+[[:alnum:]]/?)`si

wykorzystane w preg_replace. Chcę dodać warunek, że jeżeli PRZED dopasowywanym wyrażeniem jest cudzysłów, to dopasowanie ma być wykluczone. Znaczek wykluczenia to ^, ale nijak nie wiem, jak go tu zastosować. Proszę też o ewentualne słówko na temat ((?: a dokładnie znaku zapytania i dwukropka - co w tym momencie dają?
croc
(?: ... ) daje to, że obejmuje grupuje wyrażenie podobnie jak sam nawias, ale nie zapisuje go do wyniku. Bardzo przydatne.

Co do Twojego wyrażenia, to czy ma to być po prostu każdy URL bez cudzysłowu na początku? Bo Twoje wyrażenie nie jest najlepsze do szukania URL.
maviozo
Widocznie na zrozumienie tego co napisałeś, jestem za tępy, ale wyjaśnienie nic mi nie dało. Do jakiego wyniku nie zapisuje? Wstyd, ale jest to naprawdę jedna z niewielu rzeczy, których nie mogę pojąć. Irytuje mnie to, bo wielokrotnie potrzebuję tych nieszczęsnych wyrażeń i zawsze ciężko z tym walczę.

Tak, chodzi o pomijanie linków, jeżeli przed nimi jest cudzysłów.
croc
Najlepiej używać wzorców do URL wziętych z internetu. Ten jest całkiem niezły (nie przeraź się):

Kod
^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$


Czyli dla Twojego przypadku wyglądałoby to tak:

Kod
(?:^|[^"])(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?

Powinien działać idealnie. Na początek wzorca dałem fragment, który przepuści takie linki, które są na samym początku łańcucha znaków lub mają przed sobą dowolny znak inny niż cudzysłów.


A co do (?: ... ) - wszystkie funkcje preg_XXX traktują w specjalny sposób fragmenty wzorców zapisane w nawiasie. preg_match do wyników swojego działania (zmiennej podanej jako 3-ci parametr) dodaje wszystko co znajdzie, a oprócz tego wszystkie fragmenty w nawiasach. Jak dasz (?: ... ) zamiast normalnego nawiasu, to zawartość tego nawiasu nie jest przechwytywana. Pobaw się i porównaj wyniki tych instrukcji:
  1. preg_match('#Ala ma ([a-z]+)\.#', 'Ala ma kota.', $matches);
  2. print_r($matches);

oraz:
  1. preg_match('#Ala ma (?:[a-z]+)\.#', 'Ala ma kota.', $matches);
  2. print_r($matches);
maviozo
Pokaźny post. Na pewno się z nim zaznajomię. Wytłumacz mi tylko w takim razie, czy dobrze rozumuję. Kod, który zresztą też uraczyłem się z googla, ma postać:
  1. '`((?:https?|ftp)://\S+[[:alnum:]]/?)`si',
  2. '<a href="$1" rel=nofollow>$1</a> ',
  3. $txt);

Z tego co rozumiem, to w powyższym, http nie powinno być dopasowane i podstawiana pod $1 wartość powinna być bez http lub https lub ftp. Dlaczego jednak, po przepuszczeniu linka http://test.pl/test dostaję:
  1. <a href="http://test.pl/test" rel=nofollow>http://test.pl/test</a>
?

Cytat
Na początek wzorca dałem fragment, który przepuści takie linki, które są na samym początku łańcucha znaków lub mają przed sobą dowolny znak inny niż cudzysłów.

Faktycznie tak to działa, ale co z linkami, które nie są na początku łańcucha?...
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.