Найти ссылки в строке с PHP.Отличаются от обычных ссылок и ссылок на YouTube - PullRequest
0 голосов
/ 25 октября 2011

У меня есть строка, содержащая ссылки.Я хочу, чтобы мой php делал разные вещи со своими ссылками, в зависимости от URL.

Ответ:

function fixLinks($text)
{       
        $links = array();
        $text = strip_tags($text);    
        $pattern = '!(https?://[^\s]+)!'; 
        if (preg_match_all($pattern, $text, $matches)) {
            list(, $links) = ($matches);
        }

        $i = 0;
        $links2 = array();
        foreach($links AS $link) {
            if(strpos($link,'youtube.com') !== false) {
                $search = "!(http://.*youtube\.com.*v=)?([a-zA-Z0-9_-]{11})(&.*)?!";
                $youtube = '<a href="youtube.php?id=\\2" class="fancy">http://www.youtube.com/watch?v=\\2</a>';
                $link2 = preg_replace($search, $youtube, $link);
            } else {
                $link2 = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\-\w/_\.]*(\?\S+)?)?)?)@', '<a href="$1" target="_blank"><u>$1</u></a>', $link);
            }
            $links2[$i] = $link2;
            $i++;     
        }
        $text = str_replace($links, $links2, $text);
        $text = nl2br($text);

    return $text;
}

Ответы [ 2 ]

2 голосов
/ 25 октября 2011

Прежде всего, ров eregi.Это устарело и скоро исчезнет.

Тогда выполнение этого за один проход, возможно, слишком далеко.Я думаю, вам будет лучше разделить это на три фазы.

Фаза 1 выполняет поиск регулярных выражений по вашему вводу, находит все, что похоже на ссылку, и сохраняет его в списке..

Фаза 2 перебирает список, проверяет, идет ли ссылка на youtube (parse_url чрезвычайно полезна для этого), и помещает подходящую замену во второй список.

Фаза 3 : теперь у вас есть два списка, один из которых содержит исходные совпадения, а другой содержит желаемые замены.Запустите str_replace поверх исходного текста, предоставив список совпадений для параметра поиска и список замен для замен.

У этого подхода есть несколько преимуществ:

  1. Регулярное выражение дляизвлечение ссылок может быть относительно простым, так как не нужно принимать во внимание специальные имена хостов
  2. Проще отлаживать;Вы можете сбросить массивы поиска и замены до фазы 3 и посмотреть, содержат ли они то, что вы ожидаете
  3. Поскольку вы выполняете все замены за один раз, вы избегаете проблем с перекрывающимися совпадениями или заменой части уже замененнойтекст (в конце концов, замененный текст все еще содержит URL, и вы не хотите его заменять снова)
0 голосов
/ 25 октября 2011

tdammers 'ответ - это хорошо, но другой вариант - использовать preg_replace_callback. Если вы пойдете с этим, то процесс немного изменится:

  1. Создать регулярное выражение, соответствующее всем ссылкам, так же, как и его Фаза 1
  2. В обратном вызове найдите идентификатор видео YouTube. Это потребует запуска второго preg_match, что (на мой взгляд) самая большая проблема с этой техникой.
  3. Возвращает замещающую строку в зависимости от того, является ли это YouTube.

Код будет выглядеть примерно так:

function replaceem($matches) {
    $url = $matches[0];
    preg_match('~youtube\.com.*v=([\w\-]{11})~', $url, $matches);
    return isset($matches[0]) ?
        '<a href="youtube.php?id='.$matches[1].'" class="fancy">'.
        'http://www.youtube.com/watch?v='.$matches[1].'</a>' :
        '<a href="'.$url.'" title="Åben link" alt="Åben link" '.
        'target="_blank">'.$url.'</a>';
}
$text = preg_replace_callback('~(?:f|ht)tps?://[^\s]+~', 'replaceem', $text);
...