PHP stripos() return only false - php

I'm making a filter of Badword that return true if their is a bad word in a string.
but what happen is that whatever the user write the code return false.
I already tried to convert the arguments of stripos() to string (just in case) but still.
I tried preg_match() with "/$word/i", $_POST['message']
here is my function for the checking:
function MessageBad(){
$BadWord = false;
$bannedwords = file("bannedwords");
foreach($bannedwords as $word) {
if(stripos($_POST['message'], $word) !== false){
$BadWord = true;
}
}
return $BadWord;
}
but stripos($_POST['message'], $word) !== false always return false even when I enter only a badword from the bannedwods list...

By default, the strings returned by file() include the newline character at the end of each line. So $word ends with a newline, and will only match if the bad word is at the end of the line.
Use the FILE_IGNORE_NEW_LINES flag to remove the newlines.
$bannedwords = file("bannedwords", FILE_IGNORE_NEW_LINES);
You should also break out of the loop once you find a match, there's no need to keep checking other words.

Related

PHP: Regex, must contain all letters from list

Does anyone know how to write regex pattern, that does this:
let's say I have letters in array like
$letters = array('a','b','a');
and also we have a word Alabama and I want preg_match to return true, since it contains letter A two times and B. But it should return false on word Ab, because there aren't two A in that word.
Any ideas ?
EDIT: the only pattern I tried was [a,b,a] but it returns true on every word that does contain one of these letters and also doesn't check it for multiple letter occurences
I think you don't have to overcomplicate the process. You can traverse the letters and check if the exists in the word, if all the letter are there, return true. Something like this:
$letters = array('a','b','a');
$word = "Alabama";
function inWord($l,$w){
//For each letter
foreach($l as $letter){
//check if the letter is in the word
if(($p = stripos($w,$letter)) === FALSE)
//if false, return false
return FALSE;
else
//if the letter is there, remove it and move to the next one
$w = substr_replace($w,'',$p,1);
}
//If it found all the letters, return true
return TRUE;
}
And use it like this: inWord($letters,$word);
Please note this is case insensitive, if you need it case sensitive replace stripos by strpos
Must you need to use regular expressions? Even if the problem can be solved through them, the code will be very complicated.
"Manual" solution will be clearer and takes linear time:
function stringContainsAllCharacters(string $str, array $chars): bool
{
$actualCharCounts = array_count_values(str_split($str));
$requiredCharCounts = array_count_values($chars);
foreach ($requiredCharCounts as $char => $count) {
if (!array_key_exists($char, $actualCharCounts) || $actualCharCounts[$char] < $count) {
return false;
}
}
return true;
}

php - regex exact matches

I have the following strings:
Falchion-Case
P90-ASH-WOOD-WELL-WORN
I also have the following URLS which are inside a text file:
http://csgo.steamanalyst.com/id/115714004/FALCHION-CASE-KEY-
http://csgo.steamanalyst.com/id/115716486/FALCHION-CASE-
http://csgo.steamanalyst.com/id/2018/P90-ASH-WOOD-WELL-WORN
I'm looping through each line in the text file and checking if the string is found inside the URL:
// Read from file
if (stristr($item, "stattrak") === FALSE) {
$lines = file(public_path().'/csgoanalyst.txt');
foreach ($lines as $line) {
// Check if the line contains the string we're looking for, and print if it does
if(preg_match('/(?<!\-)('.$item.')\b/',$line) != false) { // case insensitive
echo $line;
break;
}
}
}
This works perfectly when $item = P90-ASH-WOOD-WELL-WORN however when $item = Falchion-Case It matches on both URL's when only the second: http://csgo.steamanalyst.com/id/115716486/FALCHION-CASE- is valid
Try modifying your regx to match the end of the line, assuming the line ends
'/('.$item.')$/'
This would match
http://csgo.steamanalyst.com/id/115714004/FALCHION-CASE-KEY- <<end of line
Basically do an ends with type match, you can do this too
'/('.$item.')\-?$/'
to optionally match an ending hyphen
You can also use a negative lookahead to negate that unwanted case:
preg_match('/(?<!-)'. preg_quote($item) .'(?!-\w)/i', $line);

exact preg_match with #

How can I preg_match exactly with that kind of search:
My value to find: #5#
My value to search: #5#;#9#
I did a simple
if (preg_match("#5#", "#5#;#9#")) { return true; } else { return false; }
And, it returns true.
The problem with that code, it's return also true if my value to compare is #51#;#55# whereas it has to be false in that case:
if (preg_match("#5#", "#51#;#55#")) { return true; } else { return false; }
Also returns true whereas I want false.
preg_match("#5#", "#51#;#55#") returns true because preg_match uses # as delimiter. In order to match #5# you have to add delimiters around the regex:
if (preg_match("/#5#/", "#51#;#55#")) { return true; } else { return false; }
This will return false.
If all you need is to find a string you know (#5#) in another string then the best way is to use function strpos(). It returns the boolean FALSE if it cannot find the string or an integer number that represents the position of the searched string into the other string.
It is faster that any preg_*() function.
$pos = strpos('#5#', '#5#;#9#');
if ($pos !== FALSE) {
echo('Found (at position '.$pos.')');
} else {
echo('Not found.');
}
You have to pay attention to the comparison operator: using $pos != FALSE is not enough because 0 == FALSE. You have to compare using === or !== to avoid this.
Using preg_match()
Your approach failed because in PHP the PCRE functions interpret the first character from the regex as a delimiter.
This means the regex in #5# is: 5. And this regex, of course, matches any 5 it finds in the string. To fix it you have to surround your regex with some delimiter (/ is usually used):
return preg_match('/#5#/', '#5#;#9#');

Test pipe delimited format with regular expression in php

I need to verify the string is in the following format, otherwise I need to return a warning message.
purple|grape juice
green|lettuce is good in salad
yellow|monkeys like bananas
red|water melon is delicious
I need it in the pipe delimited data like above, each line is split into two chunks then a new line.
If there is 3 pipes in in one line, then it is not correct.
This RegEx will validate the whole string to your specs: ^(\w+\|[\w ]+(\n|$))+$
If one of the lines is invalid, preg_match() will return false.
Note: I assumed left part will have numbers and letters only and the second the same plus space
See it live here: http://regex101.com/r/iV0tC4
So all the code you need is:
if (!preg_match($regex,$string)) trigger_error("Invalid string!",E_USER_WARNING);
Live code: http://codepad.viper-7.com/i3Hcjs
I'm not sure what you are trying to get, but if I'm guessed you need something like this:
<?
$lines = explode("\n",$str);
foreach ($lines as $lineIndex => $oneLine)
if (count(explode('|',$oneLine))>2) echo "You have an error in line ".$lineIndex;
?>
A RegExp match is all you need. Split the string by new lines, then run the RegExp match on each line, if the match returns false then end the function early (short circuit). The RegExp is essentially START_OF_LINE (^) and anything not a pipe ([^\|]) and a pipe (\|) and anything not a pipe ([^\|]) and END_OF_LINE ($).
function verify($str) {
$regex = '/^[^\|]*\|[^\|]*$/';
$all = explode("\n", $str);
foreach($all as $line) {
if(preg_match($regex, $line) == false)
return false;
}
return true;
}
echo verify("bad") === false;
echo verify("bad|bad|bad") === false;
echo verify("abc|123\nbad") === false;
echo verify("abc|123\nbad|bad|bad") === false;
echo verify("good|good") === true;
echo verify("good|good\nnice|nice") === true;

If string contains forward slash

How do i make a if statement which checks if the string contains a forward slash?
$string = "Test/Test";
if($string .......)
{
mysql_query("");
}
else
{
echo "the value contains a invalid character";
}
You can use strpos, which will make sure there is a forward slash in the string but you need to run it through an equation to make sure it's not false. Here you can use strstr(). Its short and simple code, and gets the job done!
if(strstr($string, '/')){
//....
}
For those who live and die by the manual, when the haystack is very large, or the needle is very small, it is quicker to use strstr(), despite what the manual says.
Example:
Using strpos(): 0.00043487548828125
Using strstr(): 0.00023317337036133
if(strpos($string, '/') !== false) {
// string contains /
}
From the PHP manual of strstr:
Note:
If you only want to determine if a particular needle occurs within
haystack, use the faster and less memory intensive function strpos()
instead.
Use strpos()
If it doesn't return false, the character was matched.
I compared strpos() results with 0. Somehow comparison with false did not work for me.
if (strpos($t, '/') !== 0) {
echo "No forward slash!";
}

Categories