Je veux pouvoir prendre le texte entré par l'utilisateur dans un champ de commentaire et vérifier l'expression de type URL, et s'il existe, ajoutez une balise d'ancrage (à URL) lorsque le commentaire est affiché.
J'utilise php Sur le côté serveur et JavaScript (avec jQuery) sur le client, je dois donc attendre de vérifier l'URL jusqu'à ce qu'il soit juste avant qu'il ne soit affiché? Ou ajoutez la balise d'ancrage avant d'insérer dans la base de données? P>
SO P>
<div id="commentDisplay">check out <a href="blahblah.com">blahblah.com</a> or <a href="www.thisthing.co.uk">www.thisthing.co.uk</a> or <a href="http://checkthis.us/">http://checkthis.us/</a></div>
8 Réponses :
Premier, une demande. Ne faites pas cela avant d'écrire les données à la base de données. Attendez-le plutôt avant d'afficher les données sur l'utilisateur final. Cela va réduire la confusion et vous permettra plus de flexibilité à l'avenir.
Un exemple trouvé en ligne suit: p> et un beaucoup plus complet de DARINGFIREBALL.NET : P> /**
* Replace links in text with html links
*
* @param string $text
* @return string
*/
function auto_link_text($text)
{
$pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
$callback = create_function('$matches', '
$url = array_shift($matches);
$url_parts = parse_url($url);
$text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
$text = preg_replace("/^www./", "", $text);
$last = -(strlen(strrchr($text, "/"))) + 1;
if ($last < 0) {
$text = substr($text, 0, $last) . "…";
}
return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text);
');
return preg_replace_callback($pattern, $callback, $text);
}
Cela fonctionnerait, bien que j'ai bien peur du retard (il affichera beaucoup de commentaires à la fois)
Donner un coup de feu. Je doute que vous découvriez tout décalage notable.
c'est vraiment soigné (deuxième fonction)
La première fonction ne fonctionne pas avec des tirets dans les URL, comme dans l'URL de cette page: Stackoverflow.com/questions/1959062/... .
@JonathanSamPson Lorsque j'ai utilisé la deuxième fonction avec juste un nom de domaine sans 'http: //', il s'agit d'ajouter le nom de domaine actuel au début. ex: Si je tape sur www.google.com, il montre comme www.mydomain.com/www.google.com
Personnellement, je le marquerais avec JS juste avant d'afficher, semble plus professionnel et durable que de modifier vous-même le commentaire de l'utilisateur. P>
Je préférerais faire cela sous le côté du serveur. Javascript a un "décalage"; Il ne fonctionne que lorsque l'ensemble de l'arborescence HTML DOM est chargé et affiché dans le WebBrowser. Ainsi, cela peut prendre un (bien que peu court), avant que l'URL soit reconnue et analysée. Le client peut voir que les liens ont été remplacés instantanément pendant qu'il est toujours confronté au contenu. Cela pourrait conduire à "WTF?" expériences du côté client. Ceci est aujourd'hui trop rapidement lié à la publicité / spam / spyware. Vous devriez éviter cela autant que possible. N'utilisez pas de JS pour modifier le contenu de la charge, le faire uniquement pendant les événements contrôlés par l'utilisateur (OnClick, Onchange, Onfocus, etc.). Utilisez le langage côté serveur pour modifier le contenu avant d'enregistrer ou d'afficher. P>
Donc, il suffit de rechercher un script PHP qui analyse le texte (ou utilise regex) pour construire des liens avec des liaisons complètes basés sur des URL en texte brut. Vous pouvez trouver un lot ici . Bonne chance. P>
Je suis d'accord sur la déclaration WTF et le décalage, bien que je puisse avoir à ajuster la colonne de base de données contenant le commentaire pour conserver plus de caractères pour prendre en compte ceux qui sont ajoutés par le PHP.
J'ai adapté l'option de regex de Jonathan Sampson de sorte qu'il soit plus clément sur ce qui est un domaine (pas besoin de HTTP (s) à qualifier).
http://www.google.com/ https://www.google.com/. www.google.com www.google.com. www.google.com/test google.com google.com, google.com/test 123.com/test www.123.com.au ex-ample.com http://ex-ample.com http://ex-ample.com/test-url_chars.php?param1=val1. http://ex-ample.com/test-url_chars?param1=value1¶m2=val+with%20spaces
J'ai cherché une réponse partout qui fonctionne pour tous ces cas différents sont montrés dans votre exemple. Merci d'avoir pris le temps de partager cela avec la communauté! Bon travail!
@ user1846348 est correct. Il ne fonctionnera pas non plus pour un domaine comme httpfun.com
Cela devrait être adapté de sorte que (http)? (S)? (: //)? Code> devient (https ?: //)? Code> - Je suis sûr Cela résoudrait les problèmes mentionnés précédemment. (Il faut encore mettre à jour les 1 $, 2 $, etc.)
Cela capture également des chiffres, comme 399,99
Raffinage de la réponse de Markd pour éviter les liens sur les décimales, les pourcentages, les dates numériques (10.3.2001), les adresses ellipsis et IP: fonctionne pour: p> http: //www.google.com/
https: // www.google.com strong> /.
www.google.com strong>
www.google.com strong>.
www.google.com/test strong>
google.com strong>
google.com strong>,
google.com/test strong>
www.123.com.au strong>
ex-exemple.com strong>
http: // ex-exemple.com strong>
http: // ex-exemple.com/test-url_charars.php?param1=val1 strong>.
http: // ex-exemple.com/test-url_chars?param1=value1¶m2=val+with%20Spaces strong>
ne fonctionne pas pour:
123.com/test (domaines numériques sans 'www') strong>
Continuez la presse de l'opinion populaire ........ Gardez la moyenne
Hausse de 3,8% à 3,94 millions de 3,79 millions de dollars
Édité par Andrew Brooke - 07.08.2013 19:57 (dates DD.MM.YYYY) strong>
10.1.1.1 (adresses IP) strong> p> p>
suggère simplement un plugin utile ici: liens externes code> https: / /wordpress.org/plugins/sem-external-links/ p>
Voici mon code pour formater tous les liens à l'intérieur du texte, y compris les courriels, les URL avec et sans protocole.
public function formatLinksInText($text)
{
//Catch all links with protocol
$reg = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\/\S*)?/';
$formatText = preg_replace($reg, '<a href="$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $text);
//Catch all links without protocol
$reg2 = '/(?<=\s|\A)([0-9a-zA-Z\-\.]+\.[a-zA-Z0-9\/]{2,})(?=\s|$|\,|\.)/';
$formatText = preg_replace($reg2, '<a href="//$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $formatText);
//Catch all emails
$emailRegex = '/(\S+\@\S+\.\S+)\b/';
$formatText = preg_replace($emailRegex, '<a href="mailto:$1" style="font-weight: normal;" target="_blank" title="$1">$1</a>', $formatText);
$formatText = nl2br($formatText);
return $formatText;
}
J'ai une petite mise à jour de la réponse acceptée qui fonctionne également pour des liens sans protocole (liens sans http (s): //) - avant d'être liés mais comme des liens relatifs qui ne fonctionnaient pas.
J'ai également ajouté quelques commentaires pour la documentation. P>
/**
* Replace links in text with html links
*
* @param string $text Text to add links to
* @return string Text with links added
*/
function auto_link_text( $text )
{
$pattern = "#\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'.,<>?«»ââââ])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))#";
return preg_replace_callback( $pattern, function( $matches ) {
$url = array_shift( $matches );
// force http if no protocol included
if ( !startsWith( $url, 'http' ) ) {
$url = 'http://' . $url;
}
// make link text from url - removing protocol
$text = parse_url( $url, PHP_URL_HOST ) . parse_url( $url, PHP_URL_PATH );
// remove the www from the link text
$text = preg_replace( "/^www./", "", $text );
// remove any long trailing path from url
$last = -( strlen( strrchr( $text, "/" ) ) ) + 1;
if ( $last < 0 ) {
$text = substr( $text, 0, $last ) . "…";
}
// update
return sprintf(
'<a rel="nowfollow" target="_blank" href="%s">%s</a>',
$url,
$text
);
}, $text );
}
/**
* Check strings for starting match
*
* @param string $string String to check.
* @param string $startString Startin string to match.
* @return boolean Wether string begins with startString.
*/
function startsWith( $string, $startString )
{
$len = strlen($startString);
return (substr($string, 0, $len) === $startString);
}
Je comprends ce que vous essayez d'atteindre, mais comme votre exemple est syntaxiquement invalide, je vous averti que: vous devez spécifier des URL externes avec un protocole b> (http: //), sinon Ils deviendront relatifs et indiquent votre propre domaine! Ainsi,
http://blahblah.com code> et ainsi de suite.Si vous faites ce type de manipulation avant d'insérer le commentaire dans la DB, vous aurez un problème si quelqu'un veut éditer son poste: il y aura du HTML au milieu de celui-ci ;; Donc, soit faire cette manipulation lorsque vous affichez ou stockez 2 versions du commentaire dans la DB (une "propre" et une "transformée / enrichie")
@Ballusc vous avez raison, je voulais changer cela dans l'affiché, mais j'ai eu une copie et une pâte heureux et oublié.