Matching wildcard arrays in PHP - WordPress - php

PHP code:
$search = "Who is KMichaele test";
$array = ["john","michael","adam"];
if (in_array($search, $array)) {
echo "success";
}
else
echo "fail";
I want the success output. How is it possible?

You can use array_reduce and stripos to check all the values in $array to see if they are present in $search in a case-insensitive manner:
$search = "Who is KMichaele test";
$array = ["john","michael","adam"];
if (array_reduce($array,
function ($c, $i) use ($search) {
return $c || (stripos($search, $i) !== false);
},
false))
echo "success";
else
echo "fail";
Output:
success
Edit
Since this is probably more useful wrapped in a function, here's how to do that:
$search = "Who is KMichaele test";
$array = ["john","michael","adam"];
function search($array, $search) {
return array_reduce($array,
function ($c, $i) use ($search) {
return $c || (stripos($search, $i) !== false);
},
false);
}
if (search($array, $search))
echo "success";
else
echo "fail";
$search2 = "michael";
if (search($array, $search2))
echo "success";
else
echo "fail";
Output
success
success

Here's an in_array-esque function that will ignore case and bail early on a match:
function search_array($search, $arr) {
foreach ($arr as $item) {
if (stripos($search, $item) !== false) {
return 1;
}
}
return 0;
}
$search = "Who is KMichaele test";
$array = ["john", "michael", "adam"];
if (search_array($search, $array)) {
echo "success\n";
}
else {
echo "fail\n";
}
Output
success

You can do this with a simple regx
$search = "Who is KMichaele test";
$array = ["john","michael","adam"];
$regex = '/\b('.implode('|', $array).')\b/i';
///\b(john|michael|adam)\b/i
$success = preg_match($regex, $search);
The Regex is simple
\b - matches word boundary
| or
the flag \i, case insensitive
Essential match any of the words in the list.
By using the boundary the word michael will not match kmichael for example. If you want partial word matches, just remove those.
Sandbox without the word boundry
If you include the 3rd argument
$success = preg_match($regex, $search,$match);
You can tell what the matches were. And last but not lest you can reduce it down to one line
$success = preg_match('/\b('.implode('|', $array).')\b/i', $search);

Related

PHP foreach with more condition

Is it possible to set foreach function more than 2 condition. Example like below:
$stat_cps = $_POST['stat_cp'];
$acc_idss = $_POST['acc_ids'];
$string = 'NG';
foreach ($stat_cps as $url)
{
if(strpos($string, $url) !== FALSE)
{
echo "One of the field is NG";
return true;
}
}
echo "All field is OK";
What I want is:
if $stat_cps or $acc_idss contains NG then echo "One of the field is NG";
On the above code, it's only working for $stat_cps
*stat_cps and acc_idss is from radio button form.
Anyone can give the suggestion?
"One-line" solution with array_merge, implode and strpos functions:
...
$hasNg = strpos("NG", implode(",", array_merge($stat_cps,$acc_idss)));
...
// check for 'NG' occurance
echo ($hasNg !== false)? "One of the field is NG" : "string 'NG' doesn't exists within passed data";
You can use array_merge to combine both your arrays:
http://php.net/manual/en/function.array-merge.php
$stat_cps = $_POST['stat_cp'];
$acc_idss = $_POST['acc_ids'];
$merged = array_merge($stat_cps,$acc_idss);
$string = 'NG';
foreach ($merged as $url)
{
if(strpos($string, $url) !== FALSE)
{
echo "One of the field is NG";
return true;
}
}
This will remove duplicate string keys but it doesn't look like that should be an issue here if you just want one match
From you comment try doing
$stat_cps = $_POST['stat_cp'];
$acc_idss = $_POST['acc_ids'];
$merged = array_merge($stat_cps,$acc_idss);
$match = false;
$string = 'NG';
foreach ($merged as $url)
{
if(strpos($string, $url) !== FALSE)
{
$match = true;
}
}
if($match){
echo "One of the field is NG";
}else{
echo "Everything is OK";
}
$stat_cps = $_POST['stat_cp'];
$acc_idss = $_POST['acc_ids'];
$process=0;
$string = 'NG';
foreach ($stat_cps as $url)
{
if(strpos($string, $url) !== FALSE)
{
$process=1;
}
}
foreach ($acc_idss as $url2)
{
if(strpos($string, $url2) !== FALSE)
{
$process=1;
}
}
if($process==1){
echo "One of the field is NG";
return true;
}
#header user in_array()
$stat_cps = $_POST['stat_cp'];
$acc_idss = $_POST['acc_ids'];
$string = 'NG';
foreach ($stat_cps as $url)
{
if(in_array($string, $url) !== FALSE)
{
echo "One of the field is NG";
return true;
}
}

PHP, Match line, and return value

I have multiple lines like this in a file:
Platform
value: router
Native VLAN
value: 00 01
How can I use PHP to find 'Platform' and return the value 'router'
Currently I am trying the following:
$file = /path/to/file
$contents = file_get_contents($file);
$pattern = preg_quote($searchfor, '/');
$pattern = "/^.*$value.*\$/m";
if(preg_match_all($pattern, $contents, $matches)){
echo "Found Data:\n";
echo implode("\n", $matches[0]);
}
else{
echo "No Data to look over";
}
Heres another simple solution
<?php
$file = 'data.txt';
$contents = file($file, FILE_IGNORE_NEW_LINES);
$find = 'Platform';
if (false !== $key = array_search($find, $contents)) {
echo 'FOUND: '.$find."<br>VALUE: ".$contents[$key+1];
} else {
echo "No match found";
}
?>
returns
Here is a really simple solution with explode.
Hope it helps.
function getValue($needle, $string){
$array = explode("\n", $string);
$i = 0;
$nextIsReturn = false;
foreach ($array as $value) {
if($i%2 == 0){
if($value == $needle){
$nextIsReturn = true;
}
}else{
// It's a value
$line = explode(':', $value);
if($nextIsReturn){
return $line[1];
}
}
$i++;
}
return null;
}
$test = 'Platform
value: router
Native VLAN
value: 00 01 ';
echo getValue('Platform', $test);
If the trailing spaces are a problem for you, you can use trim function.

match the first & last whole word in a variable

I use php preg_match to match the first & last word in a variable with a given first & last specific words,
example:
$first_word = 't'; // I want to force 'this'
$last_word = 'ne'; // I want to force 'done'
$str = 'this function can be done';
if(preg_match('/^' . $first_word . '(.*)' . $last_word .'$/' , $str))
{
echo 'true';
}
But the problem is i want to force match the whole word at (starting & ending) not the first or last characters.
Using \b as boudary word limit in search:
$first_word = 't'; // I want to force 'this'
$last_word = 'ne'; // I want to force 'done'
$str = 'this function can be done';
if(preg_match('/^' . $first_word . '\b(.*)\b' . $last_word .'$/' , $str))
{
echo 'true';
}
I would go about this in a slightly different way:
$firstword = 't';
$lastword = 'ne';
$string = 'this function can be done';
$words = explode(' ', $string);
if (preg_match("/^{$firstword}/i", reset($words)) && preg_match("/{$lastword}$/i", end($words)))
{
echo 'true';
}
==========================================
Here's another way to achieve the same thing
$firstword = 'this';
$lastword = 'done';
$string = 'this can be done';
$words = explode(' ', $string);
if (reset($words) === $firstword && end($words) === $lastword)
{
echo 'true';
}
This is always going to echo true, because we know the firstword and lastword are correct, try changing them to something else and it will not echo true.
I wrote a function to get Start of sentence but it is not any regex in it.
You can write for end like this. I don't add function for the end because of its long...
<?php
function StartSearch($start, $sentence)
{
$data = explode(" ", $sentence);
$flag = false;
$ret = array();
foreach ($data as $val)
{
for($i = 0, $j = 0;$i < strlen($val), $j < strlen($start);$i++)
{
if ($i == 0 && $val{$i} != $start{$j})
break;
if ($flag && $val{$i} != $start{$j})
break;
if ($val{$i} == $start{$j})
{
$flag = true;
$j++;
}
}
if ($j == strlen($start))
{
$ret[] = $val;
}
}
return $ret;
}
print_r(StartSearch("th", $str));
?>

Php check if string contains multiple words

I have looked around the internet for something that will do this but it will only work with one word.
I am trying to build a script that will detect a bad username for my site, the bad username will be detected if the username contains any of the words in an array.
Here's the code I made, but failed to work.
$bad_words = array("yo","hi");
$sentence = "yo";
if (strpos($bad_words,$sentence)==false) {
echo "success";
}
If anybody could help me, I would appreciate it.
use
substr_count
for an array use the following function
function substr_count_array( $haystack, $needle ) {
$count = 0;
foreach ($needle as $substring) {
$count += substr_count( $haystack, $substring);
}
return $count;
}
You can use this code:
$bad_words = array("yo","hi");
$sentence = "yo you your";
// break your sentence into words first
preg_match_all('/\w+/', $sentence, $m);
echo ( array_diff ( $m[0], $bad_words ) === $m[0] ) ? "no bad words found\n" :
"bad words found\n";
// returns false or true
function multiStringTester($feed , $arrayTest)
{
$validator = false;
for ($i = 0; $i < count($arrayTest); $i++)
{
if (stringTester($feed, $arrayTest[$i]) === false )
{
continue;
} else
{
$validator = true;
}
}
return $validator;
}
//www.ffdigital.net
I believe a sentence is more than one single word
Try
$badwords = array("yo","hi");
$string = "i am yo this is testing";
$word = array_intersect( $badwords,explode(" " , $string));
if(empty($word))
{
echo "Sucess" ;
}
<?php
function isUserNameCorrect()
{
Foreach($badname in $badnames)
{
if(strstr($badname, $enteredname) == false)
{
return false;
}
}
return true;
}
Maybe this helps
Unfortunately, you can't give an Array to functions strpos/strstr directly.
According to PHP.net comments, to do this you need to use (or create your own if you want) function like this:
function strstr_array($haystack, $needle)
{
if ( !is_array( $haystack ) ) {
return false;
}
foreach ( $haystack as $element ) {
if ( stristr( $element, $needle ) ) {
return $element;
}
}
}
Then, just change strpos to the new function - strstr_array:
$bad_words = array("yo","hi");
$sentence = "yo";
if (strstr_array($bad_words,$sentence)==false) {
echo "success";
}
I'd implement this as follows:
$bad_words = array("yo","hi");
$sentence = "yo";
$valid = true;
foreach ($bad_words as $bad_word) {
if (strpos($sentence, $bad_word) !== false) {
$valid = false;
break;
}
}
if ($valid) {
echo "success";
}
A sentence is valid unless it contains at least one word from $bad_words. Note the strict checking (i.e. !==), without this the check will fail when the result of strpos is 0 instead of false.
You're close. You can do it the following way:
$bad_words = array("yo","hi");
$sentence = "yo";
$match = false;
foreach($bad_words as $bad_word) {
if (strpos($bad_word,$sentence) === false) { # use $bad_word, not $bad_words
$match = true;
break;
}
}
if($match) { echo "success"; }

Using an array as needles in strpos

How do you use the strpos for an array of needles when searching a string? For example:
$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
if(strpos($string, $find_letters) !== false)
{
echo 'All the letters are found in the string!';
}
Because when using this, it wouldn't work, it would be good if there was something like this
#Dave an updated snippet from http://www.php.net/manual/en/function.strpos.php#107351
function strposa($haystack, $needles=array(), $offset=0) {
$chr = array();
foreach($needles as $needle) {
$res = strpos($haystack, $needle, $offset);
if ($res !== false) $chr[$needle] = $res;
}
if(empty($chr)) return false;
return min($chr);
}
How to use:
$string = 'Whis string contains word "cheese" and "tea".';
$array = array('burger', 'melon', 'cheese', 'milk');
if (strposa($string, $array, 1)) {
echo 'true';
} else {
echo 'false';
}
will return true, because of array "cheese".
Update: Improved code with stop when the first of the needles is found:
function strposa(string $haystack, array $needles, int $offset = 0): bool
{
foreach($needles as $needle) {
if(strpos($haystack, $needle, $offset) !== false) {
return true; // stop on first true result
}
}
return false;
}
$string = 'This string contains word "cheese" and "tea".';
$array = ['burger', 'melon', 'cheese', 'milk'];
var_dump(strposa($string, $array)); // will return true, since "cheese" has been found
str_replace is considerably faster.
$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
$match = (str_replace($find_letters, '', $string) != $string);
The below code not only shows how to do it, but also puts it in an easy to use function moving forward. It was written by "jesda". (I found it online)
PHP Code:
<?php
/* strpos that takes an array of values to match against a string
* note the stupid argument order (to match strpos)
*/
function strpos_arr($haystack, $needle) {
if(!is_array($needle)) $needle = array($needle);
foreach($needle as $what) {
if(($pos = strpos($haystack, $what))!==false) return $pos;
}
return false;
}
?>
Usage:
$needle = array('something','nothing');
$haystack = "This is something";
echo strpos_arr($haystack, $needle); // Will echo True
$haystack = "This isn't anything";
echo strpos_arr($haystack, $needle); // Will echo False
The question, is the provided example just an "example" or exact what you looking for? There are many mixed answers here, and I dont understand the complexibility of the accepted one.
To find out if ANY content of the array of needles exists in the string, and quickly return true or false:
$string = 'abcdefg';
if(str_replace(array('a', 'c', 'd'), '', $string) != $string){
echo 'at least one of the needles where found';
};
If, so, please give #Leon credit for that.
To find out if ALL values of the array of needles exists in the string, as in this case, all three 'a', 'b' and 'c' MUST be present, like you mention as your "for example"
echo 'All the letters are found in the string!';
Many answers here is out of that context, but I doubt that the intension of the question as you marked as resolved. E.g. The accepted answer is a needle of
$array = array('burger', 'melon', 'cheese', 'milk');
What if all those words MUST be found in the string?
Then you try out some "not accepted answers" on this page.
You can iterate through the array and set a "flag" value if strpos returns false.
$flag = false;
foreach ($find_letters as $letter)
{
if (strpos($string, $letter) !== false)
{
$flag = true;
}
}
Then check the value of $flag.
If you just want to check if certain characters are actually in the string or not, use strtok:
$string = 'abcdefg';
if (strtok($string, 'acd') === $string) {
// not found
} else {
// found
}
This expression searches for all letters:
count(array_filter(
array_map("strpos", array_fill(0, count($letters), $str), $letters),
"is_int")) == count($letters)
You can try this:
function in_array_strpos($word, $array){
foreach($array as $a){
if (strpos($word,$a) !== false) {
return true;
}
}
return false;
}
You can also try using strpbrk() for the negation (none of the letters have been found):
$find_letters = array('a', 'c', 'd');
$string = 'abcdefg';
if(strpbrk($string, implode($find_letters)) === false)
{
echo 'None of these letters are found in the string!';
}
This is my approach. Iterate over characters in the string until a match is found. On a larger array of needles this will outperform the accepted answer because it doesn't need to check every needle to determine that a match has been found.
function strpos_array($haystack, $needles = [], $offset = 0) {
for ($i = $offset, $len = strlen($haystack); $i < $len; $i++){
if (in_array($haystack[$i],$needles)) {
return $i;
}
}
return false;
}
I benchmarked this against the accepted answer and with an array of more than 7 $needles this was dramatically faster.
If i just want to find out if any of the needles exist in the haystack, i use
reusable function
function strposar($arrayOfNeedles, $haystack){
if (count(array_filter($arrayOfNeedles, function($needle) use($haystack){
return strpos($haystack, $needle) !== false;
})) > 0){
return true;
} else {
return false;
}
}
strposar($arrayOfNeedles, $haystack); //returns true/false
or lambda function
if (count(array_filter($arrayOfNeedles, function($needle) use($haystack){
return strpos($haystack, $needle) !== false;
})) > 0){
//found so do this
} else {
//not found do this instead
}
With the following code:
$flag = true;
foreach($find_letters as $letter)
if(false===strpos($string, $letter)) {
$flag = false;
break;
}
Then check the value of $flag. If it is true, all letters have been found. If not, it's false.
I'm writing a new answer which hopefully helps anyone looking for similar to what I am.
This works in the case of "I have multiple needles and I'm trying to use them to find a singled-out string". and this is the question I came across to find that.
$i = 0;
$found = array();
while ($i < count($needle)) {
$x = 0;
while ($x < count($haystack)) {
if (strpos($haystack[$x], $needle[$i]) !== false) {
array_push($found, $haystack[$x]);
}
$x++;
}
$i++;
}
$found = array_count_values($found);
The array $found will contain a list of all the matching needles, the item of the array with the highest count value will be the string(s) you're looking for, you can get this with:
print_r(array_search(max($found), $found));
Reply to #binyamin and #Timo.. (not enough points to add a comment..) but the result doesn't contain the position..
The code below will return the actual position of the first element which is what strpos is intended to do. This is useful if you're expecting to find exactly 1 match.. If you're expecting to find multiple matches, then position of first found may be meaningless.
function strposa($haystack, $needle, $offset=0) {
if(!is_array($needle)) $needle = array($needle);
foreach($needle as $query) {
$res=strpos($haystack, $query, $offset);
if($res !== false) return $res; // stop on first true result
}
return false;
}
Just an upgrade from above answers
function strsearch($findme, $source){
if(is_array($findme)){
if(str_replace($findme, '', $source) != $source){
return true;
}
}else{
if(strpos($source,$findme)){
return true;
}
}
return false;
}
<?php
$Words = array("hello","there","world");
$c = 0;
$message = 'Hi hello';
foreach ($Words as $word):
$trial = stripos($message,$word);
if($trial != true){
$c++;
echo 'Word '.$c.' didnt match <br> <br>';
}else{
$c++;
echo 'Word '.$c.' matched <br> <br>';
}
endforeach;
?>
I used this kind of code to check for hello, It also Has a numbering feature.
You can use this if you want to do content moderation practices in websites that need the user to type

Categories