Форум программистов, компьютерный форум, киберфорум
PHP: RegExp
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.59/125: Рейтинг темы: голосов - 125, средняя оценка - 4.59
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625

Найти и обернуть ссылки в тексте

06.03.2014, 23:49. Показов 23804. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброй ночи.

В интернете накопал регулярное выражение, которое находит в тексте ссылки и оборачивает их в тег <a></a>. Минут этой регулярки в том, что она не учитывает длинну ссылки. Если сылка будет слишком длинной, она будет показываться в одну строку. Как переделать эту регулярку, чтобы из длинных ссылок, она делала примерно следующее: http://site.ru/users/act ... age12.html

Вот регулярное выражение:

PHP
1
2
3
$text = "Сократить следующую ссылку. https://www.cyberforum.ru/newthread.php?do=newthread&f=323";
$new_text = preg_replace("~(http|https|ftp|ftps)://(.*?)(\s|\n|[,.?!](\s|\n)|$)~", '<a href="$1://$2">$1://$2</a>$3', $text);
echo $new_text;
Добавлено через 16 секунд
Или может быть у вас имеются свои варианты..
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.03.2014, 23:49
Ответы с готовыми решениями:

Обернуть все ссылки в тег <a>
Здравствуйте, выручайте, а то я уже не знаю что и думать. нужно найти в тексте из textarea все ссылки и обернуть их в тег a. Вот написал ...

Обработать ссылки в тексте
Привет! Допустим, имеется текст, в нем ссылки оформлены в виде текста, нужно эти ссылки (которые пока еще не совсем ссылки) обработать,...

Распознавание ссылки в тексте
подскажите регулярное выражение которое на 100% выявляло ссылку в тексте, в тексте могут попадаться ссылки типа ...

15
Невнимательный
 Аватар для ft4l
2834 / 1252 / 357
Регистрация: 08.02.2013
Сообщений: 7,298
Записей в блоге: 2
07.03.2014, 02:48
переделать можно....
PHP
1
2
3
4
5
6
7
8
9
10
11
12
$text = 'ссылки.
 
https://www.cyberforum.ru/newthread.php?do=newthread&f=323
https://www.cyberforum.ru/
 
';
echo $new_text = preg_replace(
    '#\b(ftps?|https?)://([^\s,]{1,17}+)([^\s,]{5}[^\s,]*(?<=([^\s,]{5}+))'
            .'|[^\s,]+)?#e'
    , '\'<a href="$1://$2$3">$1://\' . ((\'$4\')? \'$2...$4\':\'$2$3\') . \'</a>\''
    , $text
);
Но такое не вариант, работает медленно, читается плохо ...
из вариантов только preg_replace_callback(), ... с любым из таких выражением
1
365 / 372 / 89
Регистрация: 01.12.2013
Сообщений: 1,629
07.03.2014, 12:16
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Links {
 
    public static function correctLinks($text) {
        return preg_replace_callback('~(http|https|ftp|ftps)://[^\s]+~siu',
                'self::shortLink', $text);
    }
 
    private static function shortLink($matches) {
        $left = 9; //часть текста слева
        $right = 16; //часть текста справа
        $in = ' ... '; //вставка
        $enc = 'UTF-8';
        $linkText = $matches[0];
        $len = mb_strlen($linkText, $enc);
        if ($len > ($left + $right + mb_strlen($in, $enc))) {
            $linkText = mb_substr($linkText, 0, $left, $enc) .
                    $in .
                    mb_substr($linkText, $len - $right, $right, $enc);
        }
        return '<a href="' . $matches[0] . '">' . $linkText . '</a>';
    }
 
}
$text = ' http://dlinnaya/ssilka/nu-ochen-dlinnaya/vot.html yolki palki les gustoy '
        . '\n ftps://dlinnaya2/ssilka2/nu-ochen-dlinnaya2/vot2.html';
echo Links::correctLinks($text);
2
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
07.03.2014, 15:27  [ТС]
Благодарю. А как будет выглядеть регулярное выражение, если мы просто сократим длинную ссылку, до таково вида: http://site.ru/users/act.. и обернём её в тег <a></a>? Думаю, в принципе это будет намного проще.
0
365 / 372 / 89
Регистрация: 01.12.2013
Сообщений: 1,629
07.03.2014, 15:49
Цитата Сообщение от stashappy Посмотреть сообщение
до таково вида: http://site.ru/users/act.. и обернём её в тег <a></a>? Думаю, в принципе это будет намного проще.
ссылка же станет нерабочей...
0
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
07.03.2014, 15:51  [ТС]
До такого вида: <a href='http://site.ru/users/action/index.html'>http://site.ru/users/act..</a>
0
365 / 372 / 89
Регистрация: 01.12.2013
Сообщений: 1,629
07.03.2014, 16:27
А понял.. потребуется две регулярки - одна берет целиком ссылку, вторая будет резать ссылку. Имхо сложнее только получится, тем более если есть возможность использовать строковые ф-ии то лучше использовать их т.к. интерпретатор регулярок не так быстр. В приведенном примере, в ф-ии shortLinks просто обрезайте $matches[0] с помощью mb_substr до нужной длины..
1
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
07.03.2014, 18:00  [ТС]
ads. Не побоюсь признаться, ваш вариант не совсем приемлем для меня. Без обид. Мне бы что попроще.

В интернете нашёл очень хороший пример. Но и здесь, автор не учитывыет длинные ссылки.

PHP
1
2
3
4
5
6
function link_it($text) {
    $text= preg_replace("/(^|[\n ])([\w]*?)((ht|f)tp(s)?:\/\/[\w]+[^ \,\"\n\r\t<]*)/is", "$1$2<a href=\"$3\">$3</a>", $text); // поиск http://
    $text= preg_replace("/(^|[\n ])([\w]*?)((www|ftp)\.[^ \,\"\t\n\r<]*)/is", "$1$2<a href=\"http://$3\">$3</a>", $text); // поиск www
    $text= preg_replace("/(^|[\n ])([a-z0-9&\-_\.]+?)@([\w\-]+\.([\w\-\.]+)+)/i", "$1<a href=\"mailto:$2@$3\">$2@$3</a>", $text); // поиск почтового адреса
    return($text);
}
0
Невнимательный
 Аватар для ft4l
2834 / 1252 / 357
Регистрация: 08.02.2013
Сообщений: 7,298
Записей в блоге: 2
08.03.2014, 02:19
дело не в выражении... а в том что нужен вывод на основе дополнительной проверки.
или если ссылка не длинная, то без проверки к ней тоже придётся ..... лепить.

Отсюда вытекает что это можно сделать только с модификатором /e (eval в строке замены)
или двумя проходами с двумя разными выражениями(длинные/короткие ссылки)
или с помощью callback функции (во многих случаях самое оптимальное)
или ещё более рукодельные варианты...

применение (.*?)(\s|\n|[,.?!](\s|\n)|$) в вашем первом примере по сути то-же самое что и [^\s,.?!], только слишком неоптимальное и например ?. вполне себе могут присутствовать в ссылках...

последний пример тоже не лишён неоптимальности...
но это на всё на выбор кодера, как-бы на вкус и цвет...
1
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
08.03.2014, 02:28  [ТС]
Ладно. Спасибо за помощь. Попробую сам освоить регулярные выражения. Всё равно пригодятся знания. А там уж, что-нибудь придумаю что делать с сылками.
0
Невнимательный
 Аватар для ft4l
2834 / 1252 / 357
Регистрация: 08.02.2013
Сообщений: 7,298
Записей в блоге: 2
08.03.2014, 02:35
хотя нет [,.?!]\s срабатывало только с пробелами после знаков препинания

Добавлено через 1 минуту
трудно внимательно читать , когда надо не для себя :)
0
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
20.09.2014, 17:35  [ТС]
Почти всё готово. Следующий код, почти доработан.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Links {
    public static function correctLinks($text) {
        $text = preg_replace_callback('#(http|https|ftp|ftps)://[^\s]+#ui', 'self::shortLinkHttp', $text);
        return preg_replace_callback('#[www][^\s]+#ui', 'self::shortLinkWww', $text);
    }
    private static function shortLinkHttp($matches) {
        $linkText = $matches[0];
        if(mb_strlen($linkText) > 45) $linkText = mb_substr($linkText, 0, 45)."..";
        return '<a href="'.$matches[0].'" class="user_links">'.$linkText.'</a>';
    }
    private static function shortLinkWww($matches) {
        $linkText = $matches[0];
        if(mb_strlen($linkText) > 45) $linkText = mb_substr($linkText, 0, 45)."..";
        return '<a href="http://'.$matches[0].'" class="user_links">'.$linkText.'</a>';
    }   
}
Здесь возникает проблема в выражении '#[www][^\s]+#ui'. Я его сам сюда втыкнул, дополнительно. В тексте могут быть следующие варианты ссылок: "http://1234.ru" и "http://www.1234.ru". С первым вариантом проблем не возникает. Но со вторым, получается не совсем приятная ситуация. Второе регулярное выражение, заменяет в строке уже готовые ссылки, полученные в результате работы первого, регулярного выражения.

Пробовал исправлять регулярку так '#(^|\s+)[www][^\s]+#ui'. Но и этот вариант не совсем приемлем. Так как в данном случае, он захватывает ещё и пробел, добавляя его в конечный результат своего преобразования.

Как исправить данное('#[www][^\s]+#ui') регулярное выражение так, чтобы оно игнорировало ссылки типа "http://www.1234.ru", но работало только с ссылками типа "www.1234.ru", независимо от того, находится ссылка в начале текстовой строки или в её середине?

Добавлено через 4 часа 36 минут
У меня получился следующий вариант:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Links {
    public static function correctLinks($text) {
        return preg_replace_callback('#(http|https|ftp|ftps|www)([://]|[\.])[^\s]+#ui', 'self::shortLink', $text);
    }
    private static function shortLink($matches) {
        $linkText = $matches[0];
        if(mb_strlen($linkText) > 45) $linkText = mb_substr($linkText, 0, 45)."..";
        if(preg_match('#(http|https|ftp|ftps)://[^\s]+#ui', $matches[0])) {
            return '<a href="'.$matches[0].'" class="user_links">'.$linkText.'</a>';
        } else {
            return '<a href="http://'.$matches[0].'" class="user_links">'.$linkText.'</a>';
        }
    }   
}
Он конечно работает. Но он захватывает ссылки следующего вида http://1234@yandex.ru. Как переделать эту регулярку, чтобы подобные ссылки пропускались?

Code
1
'#(http|https|ftp|ftps|www)([://]|[\.])[^\s]+#ui'
Добавлено через 19 часов 6 минут
Я сделал это. Вот готовый вариант(добавил также замену email-адресов):
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Links {
    public static function correctLinks($text) {
        $text = preg_replace_callback('#(http|https|ftp|ftps|www)([\:\/]+|[\.]+)([a-zA-Z0-9_\.\-\@])+[a-zA-Z]{2,6}#ui', 'self::shortLink', $text);
        return preg_replace_callback('#[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}#ui', 'self::shortMail', $text);
    }
    private static function shortLink($matches) {
        $linkText = $matches[0];
        if(mb_strlen($linkText) > 45) $linkText = mb_substr($linkText, 0, 45)."..";
        if(preg_match('#(http|https|ftp|ftps)[\:\/]+[^\s]+#ui', $matches[0])) {
            if(preg_match('#[a-zA-Z0-9_\.\-]+@([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,6}#ui', $matches[0])) {
                return preg_replace('#(http[\:\/]+|https[\:\/]+|ftp[\:\/]+|ftps[\:\/]+|www[\.]+)#ui', '', $matches[0]);
            }
            return '<a href="'.$matches[0].'">'.$linkText.'</a>';
        } else {
            return '<a href="http://'.$matches[0].'">'.$linkText.'</a>';
        }
    }
    private static function shortMail($matches) {
        $linkText = $matches[0];
        if(mb_strlen($linkText) > 45) $linkText = mb_substr($linkText, 0, 45)."..";
        return '<a href="http://'.$matches[0].'">'.$linkText.'</a>';
    }
}
0
 Аватар для maxnemo
1 / 1 / 0
Регистрация: 29.08.2014
Сообщений: 29
29.06.2015, 13:48
попробовал ваш класс
почему-то ссылки вида http://www.example.ru/somepage.html в итоге генерируются вот так :
http://www.example.ru/somepage.html

То есть - somepage.html (URI) не находится в ссылке.
0
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
29.06.2015, 14:47  [ТС]
попробовал ваш класс
Да, код был не доработан. Вот более менее доработанный вариант. Хотя из него пришлось убрать оборачивание email адресов. Так и не смог заставить его оборачивать почтовые адреса. Право сказать, не силён в программировании.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Links {
    public static function correctLinks($text) {
        return preg_replace_callback('#(http|https|ftp|ftps|www)([\:\/]+|[\.]+)([\S])+#ui', 'self::shortLink', $text);
    }
    private static function shortLink($matches) {
        $linkText = $matches[0];
        if(mb_strlen($linkText) > 45) $linkText = mb_substr($linkText, 0, 45)."..";
        if(preg_match('#(http|https|ftp|ftps)[\:\/]+[^\s]+#ui', $matches[0])) {
            return '<a href="'.$matches[0].'" class="user_links" target="_blank">'.$linkText.'</a>';
        } else {
            return '<a href="http://'.$matches[0].'" class="user_links" target="_blank">'.$linkText.'</a>';
        }
    }
}
1
 Аватар для maxnemo
1 / 1 / 0
Регистрация: 29.08.2014
Сообщений: 29
29.06.2015, 15:26
А вот я для себя сделал и с обертыванием почты тоже, без callback-а .
С дополнительным параметром $type на длинную(для админки делал) ссылку и короткую уже для сайта.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    class Links {
        public static function text2Link($text,$type) {
            $text = preg_replace_callback('/(^|[\n ])([\w]*?)((www|ftp)\.[^ \,\"\t\n\r<]*)/is', 'self::'.$type.'Link', $text);
            $text = preg_replace_callback('/(^|[\n ])([\w]*?)((ht|f)tp(s)?:\/\/[\w]+[^ \,\"\n\r\t<]*)/is', 'self::'.$type.'Link', $text);       
            $text = preg_replace("/(^|[\n ])([a-z0-9&\-_\.]+?)@([\w\-]+\.([\w\-\.]+)+)/i", "$1<a href=\"mailto:$2@$3\">$2@$3</a>", $text);
            return ($text);
        }
        private static function longLink($matches) {
            return '<a target="_blank" href="/away/?go=' . rawurlencode($matches[0]) . '">' . $matches[0]. '</a>';
        }       
        private static function shortLink($matches) {
            $left = 9; 
            $right = 16;
            $in = ' ... ';
            $enc = 'UTF-8';
            $linkText = $matches[0];
            $len = mb_strlen($linkText, $enc);
            if ($len > ($left + $right + mb_strlen($in, $enc))) {
                $linkText = mb_substr($linkText, 0, $left, $enc) .
                        $in .
                        mb_substr($linkText, $len - $right, $right, $enc);
            }
            return '<a target="_blank" href="/away/?go=' . rawurlencode($matches[0]) . '">' . $linkText . '</a>';
        }
    };
/away/?go= это у меня отправка на редирект страничку типа с предупредждением что ссылка может быть не безопасной.
rawurlencode - кодирование ссылки, делал по этому примеру - http://lphp.ru/article/281.html
1
 Аватар для stashappy
42 / 42 / 13
Регистрация: 21.08.2011
Сообщений: 625
02.07.2015, 21:33  [ТС]
PHP
1
$enc = 'UTF-8';
Чтобы не выставлять каждый раз эту строку в своих записях, можно на самом верху страницы один раз прописать следующее:
PHP
1
mb_internal_encoding('UTF-8');
А лучше сразу вот так:
PHP
1
2
3
setlocale(LC_ALL, 'ru_RU.UTF-8');
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('UTF-8');
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.07.2015, 21:33
Помогаю со студенческими работами здесь

Регулярное выражение: вырезать все ссылки в тексте
Здравствуйте. Не могу разобраться с регулярными выражениями... Есть текст: Какой-то текст &lt;a...

Обернуть каждое слово в тексте в тег <span>
Вот код страницы которая загружает файлы : &lt;?php header(&quot;Content-Type: text/html; charset=utf-8&quot;); require...

Найти в тексте ссылки, vbs
Здравствуйте, в папке есть несколько файлов и они содержат ссылки (например:ГОСТ Р 7.0.4-2006 Система стандартов по информации,...

Как найти в тексте все ссылки на картинки
Привет Я новенький сильно не пинайте. Я понимаю что надо искать &quot;scr=&quot; Но у меня даже на этапе поиска уже не работает что-то :(...

Во что "семантичней обернуть" ссылки на источники и др. материалы
Доброго! Вопрос такой (может у кого есть опыт). Есть статья, в конце которой указываются ссылки на источники и другие дополнительные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru