[PHP] regex probleem met URL herkenning

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • pim
  • Registratie: Juli 2001
  • Laatst online: 17-09 11:39
Ik gebruik de volgende regex om een URL op te sporen:

PHP:
1
2
3
$msg = preg_replace("/(\s|\r|\n)((http(s?):\/\/)|(www\.))([\w\.]+)([\/\w+\.]+)\b/si", 
"<a href=\"http\\4://\\5\\6\\7\" target=_blank>\\3\\5\\6\\7</a>", 
$msg);


Deze heeft het probleem dat hij geen urls vervangt die na een <enter> komen, vreemd want ik gebruik toch een \n aan het begin??

Als ik het begin van de regex, (\s|\r|\n), vervang door (\b), is het bovenstaande probleem opgelost:

PHP:
1
2
3
$msg = preg_replace("/(\b)((http(s?):\/\/)|(www\.))([\w\.]+)([\/\w+\.]+)\b/si", 
"<a href=\"http\\4://\\5\\6\\7\" target=_blank>\\3\\5\\6\\7</a>", 
$msg);


Alleen nu worden ook de urls vervangen die beginnen met een v/d volgende tekens: "{}[]()^$.|*+?\".

Weet iemand hoe ik het effect van de \b modifier bereik, maar dan zonder de "rare" tekens?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

je zou natuurlijk de m modifier kunnen gebruiken (PCRE_MULTILINE), en een ^ gebruiken ipv \r|\n in je matchstring

en escape de backslashes in je matchstring eens... dan interpreteerd de regex compiler ze ook als "\r" en "\n" in plaats van het carriage return of linefeed teken dat php ervan maakt.
De rest is 'toevallig' wel goed, omdat bijvoorbeeld \s of \. niets betekent in php. Maar het getuigt gewoon van nette code stijl als je daar ook dubbele backslashes van maakt (en het voorkomt bugs mocht er ooit een nieuwe escape char worden toegevoegd in een toekomstige versie van php)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • pim
  • Registratie: Juli 2001
  • Laatst online: 17-09 11:39
Ik zocht eigenlijk de fout op de verkeerde plaats, maar de \n veranderen naar \\n was de tip die ik nodig had, thanx :) .

Het grote probleem was dat ik de \n's voor de url-regex door <br>'tjes verving i.p.v. erna |:(

Acties:
  • 0 Henk 'm!

Verwijderd

is vaker het probleem dat \ gedaan wordt ipv \\
zijn van die kleine dingen die altijd het moeilijkst zijn

Acties:
  • 0 Henk 'm!

  • pim
  • Registratie: Juli 2001
  • Laatst online: 17-09 11:39
Uiteindelijk is dit hem geworden:

PHP:
1
2
3
4
5
<?
$form_message = preg_replace("/(^|\\n| )((http(s?):\/\/)|(www\.))([\S\.]+)\b/i", 
"$1<a href=\"http$4://$5$6\" target=_blank>$5$6</a>", 
$form_message); 
?>


Elke url-regex die op php.net staat heeft wel een bug, echt niet te geloven.
Dus als je er ooit nog een nodig hebt, gebruik deze.

Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

pim schreef op 15 november 2002 @ 04:05:
Uiteindelijk is dit hem geworden:

PHP:
1
2
3
4
5
<?
$form_message = preg_replace("/(^|\\n| )((http(s?):\/\/)|(www\.))([\S\.]+)\b/i", 
"$1<a href=\"http$4://$5$6\" target=_blank>$5$6</a>", 
$form_message); 
?>


Elke url-regex die op php.net staat heeft wel een bug, echt niet te geloven.
Dus als je er ooit nog een nodig hebt, gebruik deze.
Ook deze regexp heeft zijn kuren hoor.
Alleereerst is het netter om met multiline te werken... Dat is iets bug-vaster: stel dat een url voorafgegaan wordt door een tab? Dan wordt 'ie niet herkend. Http is lang niet het enige protocol. Niet iedere url begint met www. (weleens op deze site geweest?). Een url mag ook een gebruikersnaam en wachtwoord opgeven... Wat bedoel je met [\S\.]+ ? de punt is geen whitespace, dus dat is een beetje dubbelop.

Ik stel deze wijziging voor:
/(^|\s)(https?|ftp|gopher):[\\/]{2}([a-z%0-9]+(:[a-z%0-9]+)?@)?(([a-z0-9\-]+\.)+[a-z]{2,6})\S*/im

De protocollen zijn nog niet helemaal compleet, maar hij ondersteunt wel de nieuwe TLDs (info,museum,aero).

Localhost, sweet localhost


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Als je in PHP regexes gebruikt, gebruik dan single quotes. Scheelt 80% van je backslashes. En nog iets, je kunt ook de delimiters zelf bepalen. Als je de regex in pcre gebruikt (preg_*):
code:
1
2
3
4
5
6
preg_match ( '/\/\//', $str );
// is identiek aan:
preg_match ( '~//~', $str );
// of 
preg_match ( '!//!', $str );
// whatever ;)


note to self: nieuwe voor de tiplist

[ Voor 0% gewijzigd door drm op 15-11-2002 17:58 . Reden: typo ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • pim
  • Registratie: Juli 2001
  • Laatst online: 17-09 11:39
kvdveer schreef op 15 november 2002 @ 17:53:
[...]

Ik stel deze wijziging voor:
/(^|\s)(https?|ftp|gopher):[\\/]{2}([a-z%0-9]+(:[a-z%0-9]+)?@)?(([a-z0-9\-]+\.)+[a-z]{2,6})\S*/im

De protocollen zijn nog niet helemaal compleet, maar hij ondersteunt wel de nieuwe TLDs (info,museum,aero).
Deze regex pakt alleen geen urls zonder http:// waardoor www.google.com niet gepakt zou worden..
En \s gebruik ik niet omdat urls die beginnen met ""{}[]()^$.|*+?\"." dan ook meegepakt worden, zoals:

[ img ]http://plaatje.com/plaatje.jp[ /img ]

Maar doe voor mij geen moeite meer, ik ben al tevreden..:)

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 16:51
Zou toch wel mooi zijn als hier de ideale regex word gevonden, er zijn in ieders geval al genoeg versies die niet geheel voldoen.

Acties:
  • 0 Henk 'm!

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 07-11-2023

kvdveer

Z.O.Z.

pim schreef op 16 November 2002 @ 19:48:
[...]


Deze regex pakt alleen geen urls zonder http:// waardoor www.google.com niet gepakt zou worden..
Wil je dan alsnog een hoge match-kwaliteit, zul je met meerdere regexpen moeten gaan werken. ftp.google.com zou namelijk ook wel tof zijn... :P
En \s gebruik ik niet omdat urls die beginnen met ""{}[]()^$.|*+?\"." dan ook meegepakt worden, zoals:
[ img ]http://plaatje.com/plaatje.jp[ /img ]
Goed punt... Die ga ik meenemen.
Maar doe voor mij geen moeite meer, ik ben al tevreden..:)
Het gaat er ook al niet meer om om jouw problemen op te lossen, we zijn ondertussen op zoek naar perfectie.

Localhost, sweet localhost

Pagina: 1