#php #regex #hyperlink #mention
#php #регулярное выражение #гиперссылка #упомянуть
Вопрос:
Я пытаюсь создать систему упоминаний, и до сих пор я преобразовал @username в ссылку. Но я хотел посмотреть, возможно ли, чтобы он распознавал пробелы для имен. Например: @Marie Lee
вместо @MarieLee
.
Кроме того, я пытаюсь преобразовать имя в ссылке в строчные буквы (например: profile?id=marielee
оставляя указанное показанным с прописными буквами, но не смог.
Пока это мой код:
<?php
function convertHashtags($str) {
$regex = '/@ ([a-zA-Z0-9_0] )/';
$str = preg_replace($regex, strtolower('<a href="profile?id=$1">$0</a>'), $str);
return($str);
}
$string = 'I am @Marie Lee, nice to meet you!';
$string = convertHashtags($string);
echo $string;
?>
Комментарии:
1. Это сложно, потому что что, если у вас есть
$string = 'I am @Marie Lee from Canada';
? Обратите внимание, что даже такая мощная система, как StackOverflow, не беспокоилась о пробелах в @ mentions ?2. @MonkeyZeus, понятно. :c А как насчет ссылки? Этот мне действительно нужен.
3. Ваша
convertHashTags()
функция должна будет свериться с базой данных, чтобы увидеть, является ли любая@
строка, которую вы найдете, фактическим пользователем в базе данных, и предоставить<a href>
разумно. Это верно независимо от того, разрешаете ли вы или запрещаете пробелы в@
упоминаниях.4. А как насчет какой ссылки? Ваш код, похоже, работает, если вы избавитесь от пробелов в имени пользователя
5. Почему вы хотите, чтобы ваш идентификатор был именем? Имена вряд ли уникальны. Или это просто имя пользователя, которое вы заставляете быть уникальным?
Ответ №1:
Вы можете использовать этот код с preg_replace_callback
и расширенным регулярным выражением, которое будет соответствовать всем словам, разделенным пробелами:
define("REGEX", '/@w (?:h w )*/');
function convertHashtags($str) {
return preg_replace_callback(REGEX, function ($m) {
return '<a href="profile?id=' . strtolower($m[0]) . '">$0</a>';
}, $str);
}
Если вы хотите разрешить только 2 слова, то вы можете использовать:
define("REGEX", '/@w (?:h w )?/');
Комментарии:
1. Большое тебе спасибо, @anubhava. Это сработало так, как мне было нужно! <3
Ответ №2:
Вы можете отфильтровывать usernames
данные на основе буквенно-цифровых символов, цифр или пробелов, больше ничего не извлекая для этого. Убедитесь , что хотя бы один символ совпадает , прежде чем использовать пробелы , чтобы избежать совпадения пустого места с единицей @
. Корректно работает максимум с 2 словами, разделенными пробелами, для имени пользователя, за которым следует несловесный символ (кроме пробела).
<?php
function convertHashtags($str) {
$regex = '/@([a-zA-Z0-9_] [sa-zA-Z0-9_]*)/';
if(preg_match($regex,$str,$matches) === 1){
list($username,$name) = [$matches[0] , strtolower(str_replace(' ','',$matches[1]))];
return "<a href='profile?id=$name'>$username</a>";
}
throw new Exception('Unable to find username in the given string');
}
$string = 'I am @Marie Lee, nice to meet you!';
$string = convertHashtags($string);
echo $string;
Демо: https://3v4l.org/e2S8C
Если вы хотите, чтобы текст отображался как есть в innerHTML тега привязки, вам необходимо изменить
list($username,$name) = [$matches[0] , strtolower(str_replace(' ','',$matches[1]))];
Для
list($username,$name) = [$str , strtolower(str_replace(' ','',$matches[1]))];
Демо: https://3v4l.org/dCQ4S
Комментарии:
1. Большое спасибо за вашу помощь, @nice_dev . Он работал как со строчными буквами, так и с пробелами, однако по какой-то непонятной мне причине он удаляет остальной текст и оставляет только @ mention .
2. @Elena Можете ли вы сообщить мне, каков был ваш вклад?
3. @Elena Вы имеете
'I am @Marie Lee, nice to meet you!'
в виду, что должен быть innerHTML?4. Большое тебе спасибо, @nice_dev!
5. @Elena Вы также можете добавить символы подчеркивания (_), чтобы они соответствовали им, а также в этих квадратных скобках в регулярном выражении