Найдите все вхождения списка строк в массиве внутри предложения и замените все, кроме первой буквы, тире

Мне нужно найти все вхождения массива строк (оригинальный $ list содержит более 780 элементов) в предложении, и заменить все, кроме первой буквы, штрихами html.

Это мой текущий код:

function sanitize($string) {
$list = array(
"dumb",
"stupid",
"brainless");

# replace bad words
$string = str_replace($list, '–', $string);
return $string;
}

echo sanitize('hello, i think you are not intelligent, you are actually dumb and stupid.');

Это текущий результат:

привет, я думаю, что вы не разумны, вы на самом деле — и —

Результат должен быть:

привет, я думаю, что вы не разумны, вы на самом деле d ––– и s –––––

Любые идеи о том, как подойти к этому? Спасибо!

1

Решение

Вы можете использовать этот подход на основе регулярных выражений, используя \G:

$str = 'hello, i think you are not intelligent, you are actually dumb and stupid.';
$list = array("dumb", "stupid", "brainless");

// use array_map to generate a regex of array for each word
$relist = array_map(function($s) {
return '/(?:\b(' . $s[0] . ')(?=' . substr($s, 1) . '\b)|(?!\A)\G)\pL/';
}, $list);

// call preg_replace using list of regex
echo preg_replace($relist, '$1-', $str) . "\n";

Код Демо

RegEx Demo

Выход:

hello, i think you are not intelligent, you are actually d--- and s-----.

  • \G устанавливает позицию в конце предыдущего совпадения или в начале строки для первого совпадения
  • (?!\A) отрицательный взгляд, чтобы убедиться, \G не совпадает в начале строки

Обновить:

Согласно вашим комментариям ниже вы можете использовать этот другой подход:

$str = 'word';
$relist = array_map(function($s) { return '/\b' . $s . '\b/'; }, $list);

echo preg_replace_callback($relist, function($m) {
return '<span class="bad">' . $m[0][0] . str_repeat('-', strlen($m[0])-1) . '</span>';
}, $str);

Выход:

first <span class="bad">w---</span>
2

Другие решения

Вы могли бы использовать array_map для генерации массива замен только с первой буквы и, возможно, тире для каждого заменяемого символа:

function sanitize($string) {
$list = array(
"dumb",
"stupid",
"brainless");

$repl = array_map("dashReplace", $list);

# replace bad words
$string = str_replace($list, $repl, $string);
return $string;
}

function dashReplace($str) {
return $str{0}.str_repeat("-", strlen($str)-1);
}

echo sanitize('hello, i think you are not intelligent, you are actually dumb and stupid.');

Результат для вашего примера: hello, i think you are not intelligent, you are actually d--- and s-----.

1

Ты можешь использовать preg_replace_callback но вам нужно добавить обратную косую черту для каждого элемента в $list массив.

function sanitize($string) {
$list = array(
"/dumb/",
"/stupid/",
"/brainless/");

# replace bad words
$string = preg_replace_callback($list,
function ($matches) {
return preg_replace('/\B./', '-', $matches[0]);
},
$string);
return $string;
}

echo sanitize('hello, i think you are not intelligent, you are actually dumb and stupid.');

Выход:

hello, i think you are not intelligent, you are actually d--- and s-----.

Код демо

0
По вопросам рекламы [email protected]