8

In laravel, I have a $string and a $blacklistArray

$string = 'Cassandra is a clean word so it should pass the check';
$blacklistArray = ['ass','ball sack'];

$contains = str_contains($string, $blacklistArray); // true, contains bad word

The result of $contains is true, so this will be flagged as containing a black list word (which is not correct). This is because the name below partially contains ass

Cassandra

However, this is a partial match and Cassandra is not a bad word, so it should not be flagged. Only if a word in the string is an exact match, should it be flagged.

Any idea how to accomplish this?

Wonka
  • 8,244
  • 21
  • 73
  • 121

4 Answers4

13

Docs: https://laravel.com/docs/5.5/helpers#method-str-contains

The str_contains function determines if the given string contains the given value:

$contains = str_contains('This is my name', 'my');

You may also pass an array of values to determine if the given string contains any of the values:

$contains = str_contains('This is my name', ['my', 'foo']);
set0x
  • 131
  • 6
  • Thank you for jumping in. I understand how it's used from my question, but I was after partial matches issue. – Wonka Nov 13 '17 at 02:54
  • The second way doesn't work for me, it says `TypeError: Argument 2 passed to str_contains() must be of the type string or null, array given on line 1`. It works for you? I am on laravel 5.8 – Rohan May 18 '22 at 08:43
  • 1
    $contains = Str::contains('This is my name', ['my', 'foo']); – Akash Sethi Aug 28 '22 at 20:32
7
$blacklistArray = array('ass','ball sack');

$string = 'Cassandra is a clean word so it should pass the check';



$matches = array();
$matchFound = preg_match_all(
                "/\b(" . implode($blacklistArray,"|") . ")\b/i", 
                $string, 
                $matches
              );

// if it find matches bad words

if ($matchFound) {
  $words = array_unique($matches[0]);
  foreach($words as $word) {

    //show bad words found
    dd($word);
  }

}
Diego Cespedes
  • 1,353
  • 4
  • 26
  • 47
4

Laravel Str::contains() method can check values against a work. Don't forget to use Illuminate\Support\Str;

Works on Laravel 7.x

Also accepts arrays of value. Instance:

$string = 'Cassandra is a clean word so it should pass the check'; $blacklistArray = ['ass','ball sack'];

if(Str::contains($string, $blacklistArray)){return true;}

// returns true

May not be your exact request though

DAVID AJAYI
  • 1,912
  • 20
  • 13
2

str_contains() works with strings - not with arrays, but you can loop it:

$string = 'Cassandra is a clean word so it should pass the check';
$blacklistArray = ['ass','ball sack'];

$flag = false;
foreach ($blacklistArray as $k => $v) {
    if str_contains($string, $v) {
        $flag = true;
        break;
    }
}

if ($flag == true) {
    // someone was nasty
}
Tpojka
  • 6,996
  • 2
  • 29
  • 39
  • is there a way to rewrite this as an array_map instead of a foreach? – Wonka Nov 13 '17 at 02:26
  • Thank you for this, I went with Diego since he commented on the issue earlier as well. Don't know why, but I prefer `array_map` over `foreach`. Upvoted :) – Wonka Nov 13 '17 at 02:58
  • I would go with @set0x 's solution. Except you are doing some kind of sociological/psychological/behavioral research, I can't imagine why would you need list of words tried by user. – Tpojka Nov 13 '17 at 06:31
  • It is just to stop certain bad words from certain fields. – Wonka Nov 14 '17 at 00:52
  • @set0x 's answer is your thing. `str_contains()` uses `mb_strpos()` funtion which is much faster than regular expression and you need just flag if any unwanted word was used. [This answer](https://stackoverflow.com/questions/9477984/which-is-the-fast-process-strpos-stripos-or-preg-match-in-php) is a bit old now, but can give you idea of functions' speed. – Tpojka Nov 14 '17 at 01:07
  • But `if str_contains($string, $v) {` The `Cassandra` in the `$string`, when `$v` is `ass` will flag someone was nasty, when they were not. – Wonka Nov 14 '17 at 02:58
  • You are right. I overlooked that case. Then you have to use preg_match. :) – Tpojka Nov 14 '17 at 10:38