Как преобразовать упоминания в ссылки с помощью регулярного выражения
Помогите, пожалуйста, разобраться с регулярными выражениями. Нужно, чтобы все слова, начинающиеся на @, делались ссылкой.
Получилось такое регулярное выражение:
$text = preg_replace('/\s@(.*)[^\s\,\.]+/ui', ' <a href="https://domen.ru/$1">@$1</a>', $text);
Однако если в тексте встречаются два пробела, то всё ломается. Например при обработке
@Tript по поводу заказа
почему-то выдаётся
<a href=\"https://domen.ru/Tript по поводу заказќ">@Tript по поводу заказм/a>
Если один пробел, то все работает нормально, хотя + — это же квантификатор, обозначающий одно или более вхождений.
Ответы (2 шт):
preg_replace('~(?<!\S)@([^\s,.]+)~u', '<a href="https://domen.ru/$1">$0</a>', $text)
работает. Спасибо Wiktor Stribiżew
Вы можете использовать
$text = preg_replace('~(?<!\S)@([^\s,.]+)~u', '<a href="https://domen.ru/$1">$0</a>', $text);
Модификатор u необходим, так как он включает опцию (*UTF) библиотеки PCRE, благодаря которой строка обрабатывается как массив символов Юникода, а не обчных байтов.
Значение выражения:
(?<!\S)- блок предварительного просмотра назад, требует отсутствия непробельного символа сразу перед текущей позицией в строке@- символ@([^\s,.]+)- Захватывающая подмаска №1: один и более пробельных символов (\s), запятых (,) и точек (.).
В шаблоне замены $0 соответствует всему совпадению, а $1 — только значению первой подмаски.
См. пример работы кода на PHP:
<?php
$text = '@Tript по поводу заказа';
$text = preg_replace('~(?<!\S)@([^\s,.]+)~u', '<a href="https://' . 'domen.ru/$1">$0</a>', $text);
echo $text;
// -> <a href="https://domen.ru/Tript">@Tript</a> по поводу заказа