У меня есть код,
$text = "This is a $1ut ( Y ) @ss @sshole a$$ ass test with grass and passages.";
$blacklist = array(
'$1ut',
'( Y )',
'@ss',
'@sshole',
'a$$',
'ass'
);
foreach ($blacklist as $word) {
$pattern = "/\b". preg_quote($word) ."\b/i";
$replace = str_repeat('*', strlen($word));
$text = preg_replace($pattern, $replace, $text);
}
print_r($text);
Которые возвращают следующий результат:
This is a $1ut ( Y ) @ss @sshole a$$ *** test with grass and passages.
Когда я удаляю границу слова из регулярного выражения,
$pattern = "/". preg_quote($word) ."/i";
Он возвращается:
This is a **** ***** *** ***hole *** *** test with gr*** and p***ages.
Как я могу написать регулярное выражение, чтобы оно не заменяло такие слова, как passages
, grass
и т. Д., А полностью заменяло, например, @sshole
?
1 ответ
Согласно это \b
не поддерживает ничего, кроме [A-Za-z0-9_]
.
Обратите внимание, что вам нужно экранировать свое регулярное выражение, поскольку вы генерируете его из строки (а компилятор PHP в момент создания этой строки не знает, что это регулярное выражение).
Использование Regex /(^|\s)WORD($|\s)/i
, похоже, работает.
Пример кода:
$text = "This is a $1ut ( Y ) @ss @sshole a$$ ass test with grass and passages.";
$blacklist = array(
'$1ut',
'( Y )',
'@ss',
'@sshole',
'a$$',
'ass'
);
foreach ($blacklist as $word) {
$pattern = "/(^|\\s)" . preg_quote($word) . "($|\\s)/i";
$replace = " " . str_repeat('*', strlen($word)) . " ";
$text = preg_replace($pattern, $replace, $text);
}
echo $text;
Выход:
This is a **** ***** *** ******* *** *** test with grass and passages.
Имейте в виду, что если ваша строка начинается или заканчивается одним из этих слов, мы добавим пробел к совпадению на каждом конце, что означает, что перед текстом или после текста будет пробел. Вы можете позаботиться об этом с помощью trim()
Обновление;
Также имейте в виду, что это никоим образом не учитывает пунктуацию.
the other user has an ass. and it is nice
, например, пройдет.
Чтобы победить это, вы можете расширить его еще больше:
/(^|\\s|!|,|\.|;|:|\-|_|\?)WORD($|\\s|!|,|\.|;|:|\-|_|\?)/i
Это означало бы, что вам также пришлось изменить способ, которым мы заменяем:
$text = "This is a $1ut ( Y ) @ss?@sshole you're an ass. a$$ ass test with grass and passages.";
$blacklist = array(
'$1ut',
'( Y )',
'@ss',
'@sshole',
'a$$',
'ass'
);
foreach ($blacklist as $word) {
$pattern = "/(^|\\s|!|,|\\.|;|:|\\-|_|\\?)" . preg_quote($word) . "($|\\s|!|,|\\.|;|:|\\-|_|\\?)/i";
$replace = '$1' . str_repeat('*', strlen($word)) . '$2';
$text = preg_replace($pattern, $replace, $text);
}
echo $text;
И добавьте все остальные знаки препинания и т. д.
Выход:
This is a **** ***** ***?******* you're an ***. *** *** test with grass and passages.
Похожие вопросы
Связанные вопросы
Новые вопросы
php
PHP — это открытый, мультипарадигмальный, динамически типизированный и интерпретируемый язык сценариев, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.
\b@ss\b
, но могут легко обрабатывать\bass\b
. Странный. Изменить Очевидно\b
поддерживает только ASCII: stackoverflow.com/questions/2881445/…