1

I need to find all occurrences of a array of strings (original $list has over 780 items) in a sentence, and replace everything except the first letter with html dashes.

This is my current code:

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.');

This is the current result:

hello, i think you are not intelligent, you are actually – and –</p>

The result should be:

hello, i think you are not intelligent, you are actually d––– and s–––––</p>

Any ideas on how to approach this? Thanks!

4

3 回答 3

2

You may use this regex based approach using \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";

Code Demo

RegEx Demo

Output:

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

  • \G asserts position at the end of the previous match or the start of the string for the first match
  • (?!\A) is negative lookahead to make sure \G doesn't match at line start

Update:

As per your comments below you can use this different approach:

$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);

Output:

first <span class="bad">w---</span>
于 2018-02-22T16:58:57.253 回答
1

You could use array_map to generate an array of replacements with the first letter only and optionally a dash for each character that was replaced:

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.');

Result for your example is: hello, i think you are not intelligent, you are actually d--- and s-----.

于 2018-02-22T16:51:14.837 回答
0

You can use preg_replace_callback but you need to add backslash to each item in $list array.

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.');

Output:

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

Code demo

于 2018-02-22T17:05:18.330 回答