Check if any value in an array exists within a haystack string - php

I have a string like abcdefg123hijklm. I also have an array which contains several strings like [456, 123, 789].
I want to check if the number in the middle of abcdefg123hijklm exists in the array.
How can I do that? I guess in_array() won't work.

So you want to check if any substring of that particular string (lets call it $searchstring) is in the array?
If so you will need to iterate over the array and check for the substring:
foreach($array as $string)
{
if(strpos($searchstring, $string) !== false)
{
echo 'yes its in here';
break;
}
}
See: http://php.net/manual/en/function.strpos.php
If you want to check if a particular part of the String is in the array you will need to use substr() to separate that part of the string and then use in_array() to find it.
http://php.net/manual/en/function.substr.php

Another option would be to use regular expressions and implode, like so:
if (preg_match('/'.implode('|', $array).'/', $searchstring, $matches))
echo("Yes, the string '{$matches[0]}' was found in the search string.");
else
echo("None of the strings in the array were found in the search string.");
It's a bit less code, and I would expect it to be more efficient for large search strings or arrays, since the search string will only have to be parsed once, rather than once for every element of the array. (Although you do add the overhead of the implode.)
The one downside is that it doesn't return the array index of the matching string, so the loop might be a better option if you need that. However, you could also find it with the code above followed by
$match_index = array_search($matches[0], $array);
Edit: Note that this assumes you know your strings aren't going to contain regular expression special characters. For purely alphanumeric strings like your examples that will be true, but if you're going to have more complex strings you would have to escape them first. In that case the other solution using a loop would probably be simpler.

You can do it reversely. Assume your string is $string and array is $array.
foreach ($array as $value)
{
// strpos can return 0 as a first matched position, 0 == false but !== false
if (strpos($string, $value) !== false)
{
echo 'Matched value is ' . $value;
}
}

Use this to get your numbers
$re = "/(\d+)/";
$str = "abcdefg123hijklm";
preg_match($re, $str, $matches);
and ( 123 can be $matches[1] from above ):
preg_grep('/123/', $array);
http://www.php.net/manual/en/function.preg-grep.php

Related

Warning: stripos() expects at least 2 parameters in php

I wrote a simple function in php and passing arguments to uppercase the letters based on passing array index value but I'm getting this error
Warning: stripos() expects at least 2 parameters
what I'm doing wrong can anyone suggest me.
i'm newbie to php just starts learning.
<?php
function doCapital($string, $array)
{
$stringArray = explode(",", $string);
for( $i=0; $i<count($stringArray); $i++)
{
if(stripos($stringArray)>-1){
$stringArray[$i] = $stringArray[$i].ucfirst();
echo $stringArray[$i];
}
}
return implode(" ",$stringArray);
}
echo doCapital('abcd', [1,2]);
Apologies, on re-reading my last answer I realise that it did seem very unfriendly - I bashed out a quick answer and didn't read it back. What I was trying to say is that with errors like this the quickest solutions to go to the php manual and check the required parameters - which in this case is a needle and a haystack (i.e something to search, and something to search in).
You will likely find the same error here
$stringArray[$i] = $stringArray[$i].ucfirst(); as ucfirst requires a string to be passed - here you're using it like jQuery so php thinks you are trying to concatenate a string, it should say ucfirst($stringArray[$i])
you also can't explode with a comma unless your string contains them, so in the example you have you would receive the same string back, I think you mean to use something like str_split
also I would reiterate that I think you need to use in_array for what you're trying to achieve, like this:
function doCapital($string, $array)
{
$stringArray = str_split($string);
foreach($stringArray as $key => $value)
{
//see if the key exists in the array of characters to change the case for
//and update if it does
if(in_array($key,$array)){
$stringArray[$key] = ucfirst($value);//thinking about it I might just use strtoupper since there's only one letter anyway - I'm not sure that there's any real performance benefit either way
}
}
return implode("",$stringArray);
}
echo doCapital('abcd', [1,2]); //outputs aBCd
stripos - Find the position of the first occurrence of a case-insensitive substring in a string
You are missing the second parameter, The correct syntax to use the function stripos is
stripos ($haystack ,$needle);
Here
$haystack -> The string in which you are searching
$needle -> The substring
For example :
$findme = 'x';
$mystring1 = 'xyz';
$pos1 = stripos($mystring1, $findme);
if ($pos1 !== false) {
echo "We found '$findme' in '$mystring1' at position $pos1";
}

Can we use Bitwise operator "|" with strpos in php?

Can we use Bitwise operator "|" with strpos in php?
I need to check if a0,a1,a2,a5 strings are exists in the given $status variable.
My code is given bellow.My code will return values(position) only when the status variable have value=a0 or a1 or a2 or a5.It will return false when $status='a1 test string.
$status='a1 test string';
echo strpos("|a0|a1|a2|a5|", $status);
No, you cannot. Documentation does not mention anything remotely similar:
strpos — Find the position of the first occurrence of a substring in
a string
Find the numeric position of the first occurrence of needle in the
haystack string.
Parameters
haystack The string to search in.
needle If needle is not a string, it is converted to an integer and
applied as the ordinal value of a character.
offset If specified, search will start this number of characters
counted from the beginning of the string. If the offset is negative,
the search will start this number of characters counted from the end
of the string.
In fact, it wouldn't make much sense to implement such feature since you already have a full-fledged regular expression engine:
$has_substrings = (bool)preg_match('/a0|a1|a2|a5/u', $status);
You can use it like this. Here | means or
<?php
$status='a1 test string';
if(preg_match("/\b(a0|a1|a2|a5)\b/", $status))
{
echo "Matched";
}
Can we use Bitwise operator "|" with strpos in php?
as a Bitwise operator | - No
as a literal symbol | - Yes
You cannot do that with a single string search. You need to use either a regular expression which can test for multiple options at once, or you need to iterate over your search terms.
Sahil Gulati gave a simple example for a regular expression based approach.
Here is a simple iteration based approach:
<?php
$status = 'a1 test string';
$search = explode('|', substr("|a0|a1|a2|a5|", 1, -1));
// would be much easier to start with an array of search tokens right away:
// $search = ['a0', 'a1', 'a2', 'a5'];
$result = false;
array_walk($search, function($token) use ($status, &$result) {
$result = (FALSE!==strpos($status, $token)) ? true : $result;
});
var_dump($result);

PHP match string, is fnmatch right for the job

I'm trying to figure out how I can compare values from an array against a particular string.
Basically my values look like chrisx001, chrisx002, chrisx003, chrisx004, bob001
I was looking at fnmatch() but I'm not sure this is the right choice, as what I want to do is keep chrisx--- but ignore bob--- so I need to wildcard the last bit, is there a means of doing this where I can be like
if($value == "chrisx%"){/*do something*/}
and if thats possible is it possible to double check the % value as int or similar in other cases?
Regex can tell you if a string starts with chrisx:
if (preg_match('/^chrisx/', $subject)) {
// Starts with chrisx
}
You can also capture the bit after chrisx:
preg_match('/^chrisx(.*)/', $subject, $matches);
echo $matches[1];
You could filter your array to return a second array of only those entries beginning whith 'chris' and then process that filtered array:
$testData = array ( 'chrisx001', 'chrisx002', 'chrisx003', 'chrisx004', 'bob001');
$testNeedle = 'chris';
$filtered = array_filter( $testData,
function($arrayEntry) use ($testNeedle) {
return (strpos($arrayEntry,$testNeedle) === 0);
}
);
var_dump($filtered);

PHP in_array Find Any Matches

I am trying to figure out how to match any words within an array. For example, the code bellow works for finding "Test Name" within an array but does not find "Another Test Name" (due to the word "Another") within the array. Any ideas?
if (in_array($html[$i], $eventsarray))
{
$topeventaa = "yes";
}
else
{
$topeventaa = "no";
}
Taken from http://php.net/manual/en/function.in-array.php
<?php
/**
* Takes a needle and haystack (just like in_array()) and does a wildcard search on it's values.
*
* #param string $string Needle to find
* #param array $array Haystack to look through
* #result array Returns the elements that the $string was found in
*/
function find ($string, $array = array ())
{
foreach ($array as $key => $value) {
unset ($array[$key]);
if (strpos($value, $string) !== false) {
$array[$key] = $value;
}
}
return $array;
}
?>
If you want to match any of the words to those in your array, you may want to use explode on your string and then check each token as you do in your example.
We probably need more information, but you can create variable with the pattern matching you need with preg_match and pass it as the argument in your search.
preg_replace and str_replace may be helpful, depending on what exactly you're trying to accomplish.
You may want to look into recursive function calls, like when traversing through all the directories within a directory tree.
I'd splice the array up to the index where it was found, leaving the remainder to be passed back into the same function to search through again.
Depending on what results you want from knowing the number of occurrences of words within a string could we then start to break down the problem and write some code.
Justin, there's no direct way--no existing built-in function--to do what I believe you seek; you must iterate over the array yourself, along the lines of
$topeventaa = "no";
for ($eventsarray as $key=>$value){
if (0 <= strpos($html[$i], $eventsarray[$key])) {
$topeventaa = "yes";
break;
}
}
Use preg_grep instead of in_array to find all elements of an array matching a given pattern.

Get more backreferences from regexp than parenthesis

Ok this is really difficult to explain in English, so I'll just give an example.
I am going to have strings in the following format:
key-value;key1-value;key2-...
and I need to extract the data to be an array
array('key'=>'value','key1'=>'value1', ... )
I was planning to use regexp to achieve (most of) this functionality, and wrote this regular expression:
/^(\w+)-([^-;]+)(?:;(\w+)-([^-;]+))*;?$/
to work with preg_match and this code:
for ($l = count($matches),$i = 1;$i<$l;$i+=2) {
$parameters[$matches[$i]] = $matches[$i+1];
}
However the regexp obviously returns only 4 backreferences - first and last key-value pairs of the input string. Is there a way around this? I know I can use regex just to test the correctness of the string and use PHP's explode in loops with perfect results, but I'm really curious whether it's possible with regular expressions.
In short, I need to capture an arbitrary number of these key-value; pairs in a string by means of regular expressions.
You can use a lookahead to validate the input while you extract the matches:
/\G(?=(?:\w++-[^;-]++;?)++$)(\w++)-([^;-]++);?/
(?=(?:\w++-[^;-]++;?)++$) is the validation part. If the input is invalid, matching will fail immediately, but the lookahead still gets evaluated every time the regex is applied. In order to keep it (along with the rest of the regex) in sync with the key-value pairs, I used \G to anchor each match to the spot where the previous match ended.
This way, if the lookahead succeeds the first time, it's guaranteed to succeed every subsequent time. Obviously it's not as efficient as it could be, but that probably won't be a problem--only your testing can tell for sure.
If the lookahead fails, preg_match_all() will return zero (false). If it succeeds, the matches will be returned in an array of arrays: one for the full key-value pairs, one for the keys, one for the values.
regex is powerful tool, but sometimes, its not the best approach.
$string = "key-value;key1-value";
$s = explode(";",$string);
foreach($s as $k){
$e = explode("-",$k);
$array[$e[0]]=$e[1];
}
print_r($array);
Use preg_match_all() instead. Maybe something like:
$matches = $parameters = array();
$input = 'key-value;key1-value1;key2-value2;key123-value123;';
preg_match_all("/(\w+)-([^-;]+)/", $input, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$parameters[$match[1]] = $match[2];
}
print_r($parameters);
EDIT:
to first validate if the input string conforms to the pattern, then just use:
if (preg_match("/^((\w+)-([^-;]+);)+$/", $input) > 0) {
/* do the preg_match_all stuff */
}
EDIT2: the final semicolon is optional
if (preg_match("/^(\w+-[^-;]+;)*\w+-[^-;]+$/", $input) > 0) {
/* do the preg_match_all stuff */
}
No. Newer matches overwrite older matches. Perhaps the limit argument of explode() would be helpful when exploding.
what about this solution:
$samples = array(
"good" => "key-value;key1-value;key2-value;key5-value;key-value;",
"bad1" => "key-value-value;key1-value;key2-value;key5-value;key-value;",
"bad2" => "key;key1-value;key2-value;key5-value;key-value;",
"bad3" => "k%ey;key1-value;key2-value;key5-value;key-value;"
);
foreach($samples as $name => $value) {
if (preg_match("/^(\w+-\w+;)+$/", $value)) {
printf("'%s' matches\n", $name);
} else {
printf("'%s' not matches\n", $name);
}
}
I don't think you can do both validation and extraction of data with one single regexp, as you need anchors (^ and $) for validation and preg_match_all() for the data, but if you use anchors with preg_match_all() it will only return the last set matched.

Categories