note 85501 modified in function.in-array by danbrown
| From: | danbrown@php.net | Date: | Mon, 08 Jun 2009 21:39:20 +0000 |
| Subject: | note 85501 modified in function.in-array by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-156493@lists.php.net to get a copy of this message | ||
Here's a function that does an in_array, but takes wildcards in the needle, and also can be
case sensitive/insensitive...
A few points:
-It doesn't use foreach, but for, which is quicker
-I didn't use regex to search with a wildcard for the reason that the needle could be
unpredictable if it's user-input, and rather than having to escape metacharacters, I decided it
would be easier to do a plain text comparison.
-Needles with wildcards can come in many forms such as:
Str*ng
S*r*ng*
*rng
*i*n*
so a split is being done on that string, and each part is then compared with the current item. If
the first part is not found, the comparison is done, and we move on. If it IS found, we move on to
the next part of the needle, while chopping off the initial part of the haystack string. This is to
ensure that each comparison of a needle part is looking at the next part of the haystack string.
For example:
needle: "Bo*bo"
haystack[0] = "Bob is lazy"
On the first pass, when searching "Bo", we then modify the haystack[0] to be: "b is
lazy" so that "bo" is compared with that. Otherwise, we'd be comparing
"bo" with "Bob is lazy", and returning true incorrectly.
I haven't fully tested the function, so let me know if you spot any bugs, or have any
questions.
<?php
function in_wildarray($needle, $haystack, $case_sensitive=true) {
$is_wild = (strpos($needle,"*")===true)? true : false;
$needles = ($is_wild)? explode("*", $needle) : array();
$needle = ($case_sensitive)? $needle : strtolower($needle);
for($i=0;$i<count($haystack);$i++) {
$haystack_str = ($case_sensitive)? haystack[$i] : strtolower($haystack[$i]);
if ($is_wild) {
$found = false;
for($x=0;$x<count($needles);$x++) {
$needle_part = trim($needles[x]);
$needle_index = strpos($haystack_str, $needle_part);
if ($needle_index===false) {
$found = false;
break; //break out of the loop, because string part is not found in the haystack
string
} else {
$found = true;
//chop off the start of the string to the needle_index
//so we can be sure that the found items are in the correct order
//and we are avoiding the potential of finding duplicate characters
$haystack_str = substr($haystack_str, 0, $needle_index);
}
}
if ($found) { return true; }
} elseif (!$is_wild && $haystack_str == $needle) {
return true;
}
}
return false;
}
?>
As the code is right now, when there are wild cards, it will treat the initial segment as though
it's preceded with a wild card. In other words, the first segment will be searched, not simply
at the beginning of the string, but anywhere. Because it's a simple fix, I'll leave it to
others. :)
--was--
Here's a function that does an in_array, but takes wildcards in the needle, and also can be
case sensitive/insensitive...
A few points:
-It doesn't use foreach, but for, which is quicker
-I didn't use regex to search with a wildcard for the reason that the needle could be
unpredictable if it's user-input, and rather than having to escape metacharacters, I decided it
would be easier to do a plain text comparison.
-Needles with wildcards can come in many forms such as:
Str*ng
S*r*ng*
*rng
*i*n*
so a split is being done on that string, and each part is then compared with the current item. If
the first part is not found, the comparison is done, and we move on. If it IS found, we move on to
the next part of the needle, while chopping off the initial part of the haystack string. This is to
ensure that each comparison of a needle part is looking at the next part of the haystack string.
For example:
needle: "Bo*bo"
haystack[0] = "Bob is lazy"
On the first pass, when searching "Bo", we then modify the haystack[0] to be: "b is
lazy" so that "bo" is compared with that. Otherwise, we'd be comparing
"bo" with "Bob is lazy", and returning true incorrectly.
I haven't fully tested the function, so let me know if you spot any bugs, or have any
questions.
<?php
function in_wildarray($needle, $haystack, $case_sensitive=true) {
$is_wild = (strpos($needle,"*")===true)? true : false;
$needles = ($is_wild)? explode("*", $needle) : array();
$needle = ($case_sensitive)? $needle : strtolower($needle);
for($i=0;$i<count($haystack);$i++) {
$haystack_str = ($case_sensitive)? haystack[$i] : strtolower($haystack[$i]);
if ($is_wild) {
$found = false;
for($x=0;$x<count($needles);$x++) {
$needle_part = trim($needles[x]);
$needle_index = strpos($haystack_str, $needle_part);
if ($needle_index===false) {
$found = false;
break; //break out of the loop, because string part is not found in the haystack
string
} else {
$found = true;
//chop off the start of the string to the needle_index
//so we can be sure that the found items are in the correct order
//and we are avoiding the potential of finding duplicate characters
$haystack_str = substr($haystack_str, 0, $needle_index);
}
}
if ($found) { return true; }
} elseif (!$is_wild && $haystack_str == $needle) {
return true;
}
}
return false;
}
?>
http://php.net/manual/en/function.in-array.php