4

Вопрос по linkify, regex, php – Функция Linkify Regex PHP Daring Fireball Метод

Итак, я знаю, что есть множество связанных вопросов по SO, но ни один из них не является тем, что я ищу. Я пытаюсь реализовать функцию PHP, которая преобразует текстовые URL-адреса из сгенерированного пользователем поста в ссылки. Я использую «улучшенный». Regex от Daring Fireball к нижней части страницы:http://daringfireball.net/2010/07/improved_regex_for_matching_urls Функция ничего не возвращает, и я не уверен, почему.

<?php
if ( false === function_exists('linkify') ):   
  function linkify($str) {
$pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';     
return preg_replace($pattern, "<a href=\"\\0\" rel=\"nofollow\" target=\"_blank\">\\0</a>", $str);      
}
endif;
?>

Может кто-нибудь, пожалуйста, помогите мне заставить это работать? Спасибо!

  • @Даже это потому, что новая ссылка должна включатьhttp:// префикс вhref приписывать. Я не думаю, что вы можете сделать это с помощью одного вызова функции. Пытатьсяpreg_replace_callback и оператор if, который будет предшествоватьhttp:// когда необходимо.

    от
  • $url = preg_match('!^http?s://!i', $input) ? $input : "http://$input"; следует изменить на$url = preg_match('!^https?://!i', $input) ? $input : "http://$input"; Вопросительный знак просто нужно было перенести на одно место.

    от Jeff
  • Благодарю. Постараюсь избежать ответов без объяснения причин в будущем.

    от
  • Спасибо, @d_inevitable! Похоже, что теперь ссылки распознаются правильно. Прекрасно работает с ссылками, начинающимися с «http:». Однако для чего-то вроде & quot; www.google.com & apos; адрес новой вкладки показывает «http // www.mysite.com / directory / www.google.com»; Я немного новичок - большое спасибо!

    от Jeff
  • Извините, я только что обновил свой ответ сейчас.

    от
  • Этот точный вопрос возник раньше, но его действительно сложно найти в Google. Но включенerror_reporting сказал бы тебеinstantly.

    от mario
  • 3

    Я искал

    чтобы просто получить URL-адреса из строки, используя тот же регулярное выражение из ответа вышеd_inevitable и я не хотел превращать их в ссылки или заботиться об остальной части строки, я хотел только URL-адреса в строке, поэтому я так и сделал. Надеюсь, поможет.

    /**
     * Returns the urls in an array from a string.
     * This dos NOT return the string, only the urls with-in.
     */
    function get_urls($str){
    
        $regex = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
        preg_match_all("#$regex#i", $str, $matches);
        $urls = $matches[0];
        return $urls;
    
    }
    

  • 10

    Попробуй это:

    $pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`\!()\[\]{};:\'".,<>?«»“”‘’]))';     
    return preg_replace("!$pattern!i", "<a href=\"\\0\" rel=\"nofollow\" target=\"_blank\">\\0</a>", $str); 
    

    РНР & APOS; spreg функция нужнаразделители,i в конце делает его нечувствительным к регистру

    Update

    Если вы используете# как разделитель, вам не нужно избегать! в шаблоне как таковом используйте исходную строку шаблона (шаблон не имеет#): "#$pattern#i"

    Update 2

    Чтобы убедиться, что ссылки верны, сделайте это:

    $pattern = '(?xi)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))';
    return preg_replace_callback("#$pattern#i", function($matches) {
        $input = $matches[0];
        $url = preg_match('!^https?://!i', $input) ? $input : "http://$input";
        return '<a href="' . $url . '" rel="nofollow" target="_blank">' . "$input</a>";
    }, $str); 
    

    Теперь добавлюhttp:// на URL, чтобы браузер не думал, что это относительная ссылка.