Darkwind
Darkwind

Reputation: 345

str_replace replace only match words

I have this PHP function to replace words in text from my list file with some words

My function

function replace_text_wps($text){

$dir = plugin_dir_path( __FILE__ );
   $file= $dir."bad2.list";

$badlist = file($file, FILE_IGNORE_NEW_LINES);
$replace = '[censored]';

    $text = str_replace($badlist, $replace, $text);
    return $text;
}

For example I have word ABC in my bad2.list

When I enter text ABC my function change ABC to [censored] , but if I enter word DFGABC in change it to DFG[censored]

How to replace only match words from my file? Im new in PHP? sorry for noob questions

Update:

HD, thank you! your solution works for me!

This is work version

function replace_text_wps($text){

$dir = plugin_dir_path( __FILE__ );
   $file= $dir."bad2.list";

$badlist = file($file, FILE_IGNORE_NEW_LINES);

$replacement = "[CENSORED]";
$badlist = array_map(function($v) { return "\b". $v ."\b"; }, $badlist);
foreach($badlist as $f) {
    $text = preg_replace("/".$f."/u", $replacement, $text);


    return $text;
}

Upvotes: 1

Views: 2676

Answers (4)

Darkwind
Darkwind

Reputation: 345

Update:

HD, thank you! your solution works for me!

This is work version

function replace_text_wps($text){

$dir = plugin_dir_path( __FILE__ );
   $file= $dir."bad2.list";

$badlist = file($file, FILE_IGNORE_NEW_LINES);

$replacement = "[CENSORED]";
$badlist = array_map(function($v) { return "\b". $v ."\b"; }, $badlist);
foreach($badlist as $f) {
    $text = preg_replace("/".$f."/u", $replacement, $text);


    return $text;
}

Upvotes: 0

Martin
Martin

Reputation: 22760

There are several competing issues here, some of them brought up by FluxCoders answer.

It's a case of defining what is a word, you may think that "yes, this is a word" contains 5 words, but if you used a spaces system to distinguish words such as

$badwords = array(" yes ", " this "); 
$text = "yes, this is a word"; 
print str_replace($badwords, "[censored]", $text);

The output will be "yes, [censored] is a word";

because Spaces do not define wordshapes; words can be wrapped in anything from new line characters \n to full stops, various punctuation marks as well as even not having spaces, try the same system above but:

$text = "this";

It will not replace the offending word because the word is not neatly wrapped in a whitespace each side.

There is also issues such as do you define a hyphen as a word break? is "yes-sir" a word you want to replace the "yes" from? or only when the yes is a single worded entity? ...This reminds me of when I saw a online dating site that removed the word "cocktails" because it contained a rude word.

So.... How can we do this?

Regular Expression Matching, using the PHP function preg_replace and reading this stack overflow question and answers. I don't see the need to repeat what is in that question here, but more this post is about outlining the numerous pitfalls of trying to do a regex intelligent find and replace using a simplistic string replacement function.

Regex Example


Please also note that your current function is not case sensitive so you will not be matching CaMelcaSe, or CAPITALISED versions of bad words.

And if you decide out of lazy ease to simply add whitespace to your searches you must remember you will also need to add the same whitespace to preserve format to your replacement text as well.

Upvotes: 1

momouu
momouu

Reputation: 711

You can use preg_replace() instead

$replace = '[censored]';

    $text = preg_replace("/\b$text\b/", $replace, $badlist);
    return $text;

Upvotes: 1

FluxCoder
FluxCoder

Reputation: 1276

You could use an array, so if you're bad2.list file has all of the 'bad' words inside of it on each line, so like one word per line, you could do something like this:

$file = file_get_contents("bad2.list"); //Should be a .txt....
$words = explode("\n", $file); //Explodes into a Array on each new line.

$message = "DFGABC";

foreach($words AS $word){
    $message = str_replace($word, "[censored]", $message);
}

echo $message;

A possible fix would be to add a space after the word that you want to censor, or you could do it automatically by adding $word = $word.' '; before the str_replace();

The following will work as you asked for.

Upvotes: 0

Related Questions