The main string contains parts which are separated by #
I need to check if the incoming string contains any of the banned keys.
In real example the keys are made by md5($var), each key 32 character length. Number of keys are variable in both $banned_keys and $incoming_keys1
$banned_keys = 'abc1#abc2#abc3#abc4';
$incoming_keys1='asd1#asd2#asd3#asd4'; //should pass no banned key found
$incoming_keys2='asd1#asd2#asd3#abc3'; //Should fail, contains banned key 'abc3'
$banned_array = explode('#', $banned_keys);
$incoming_array = explode('#', $incoming_keys);
// compute intersection of two sets
if( array_intersect($banned_array, $incoming_array) )
...
Try converting the strings to arrays using explode('#',$string) for both the incoming and the banned keys, then use in_array() to check.
For example
$banned = explode('#','abc1#abc2#abc3#abc4');
$incoming = explode('#','asd1#asd2#asd3#asd4');
if(in_array($banned,$incoming)){
//fail
}
There may be a better way, but this should work :)
You could 'explode' the strings to transform them into arrays and then match the array entries (if the intersection contains any entries, at least one banned key is provided):
$banned_keys_ary = explode('#', $banned_keys);
$incoming_keys_ary = explode('#', $incoming_keys);
if (count(array_intersect($incoming_keys_ary, $banned_keys_ary)) > 0)
{
// fail, at least one banned key found
}
else
{
// pass, no banned keys found
}
Try following:
$banned_keys_array = explode("#", $banned_keys);
$incoming_keys_arr = explode("$", $incoming_keys);
$is_valid_key = true;
foreach($incoming_keys_arr as $key) {
if (in_array($key, $banned_keys_array) {
// Invalid key found;
$is_valid_key = false;
break;
}
}
// check $is_valid_key here
Try looking here:
http://www.webcheatsheet.com/php/regular_expressions.php#match
and for the Regular Expression..
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
I'm still new at using Regular Expression..
I guess for your problem, the pattern would be...
/abc1|abc2|abc3|abc4/g
then the could should be..
<?php
$subject = "asd1#asd2#asd3#asd4";
$pattern = '/abc1|abc2|abc3|abc4/g';
if (preg_match($pattern, $subject, $matches)) {
echo "Match was found <br />";
echo $matches[0];
}
?>
The preg_match() function returns 1 if a match is found and 0 otherwise.
Related
I need to write a program to find a word in jumbled letters.For eg:Consider the string $example = "ahwerlyp"; I need to find the word help from the string.How can i Find it.Any help would be appreciated.
I have tried to use substr() function but it only return the string.if it is all in same line,otherwise it return zero
<?php
$example = "ahwerlyp";
$findword = "help";
/**how to find the word help from it**/
if($findword is present in $example)
{
echo "exists";
}
?>
Split each word into an array containing all the individual letters. (Can be done for example using preg_split('//u', 'word', -1, PREG_SPLIT_NO_EMPTY))
For each word, count how many times each letter occurs - array_count_values gives you an array with the input array values (our individual letters) as keys, and the count as value.
Loop over the counted letters from the second word, and check if the count of the same letter in the first word is greater or equal at least. If that is not the case for any of the letters from the second word, it is not “contained” in the first one.
Let’s wrap all that into a nice little function, and we get the following:
function does_a_contain_b($a, $b) {
// split both words into individual letters, and count their occurrences
$letters_given = array_count_values(preg_split('//u', $a, -1, PREG_SPLIT_NO_EMPTY));
$letters_needed = array_count_values(preg_split('//u', $b, -1, PREG_SPLIT_NO_EMPTY));
// we assume b is going to be contained in a for now
$contained = true;
foreach($letters_needed as $letter => $count) {
// if the letter from 2nd word does not occur in the 1st one at all,
// or the count in 2nd is not at least equal to that of 1st,
// we set our flag to false, and break out of the loop
if(!isset($letters_given[$letter]) || $letters_given[$letter] < $count) {
$contained = false;
break;
}
}
return $contained;
}
// a couple of test cases
var_dump(
does_a_contain_b('ahwerlyp', 'help'), // true
does_a_contain_b('ahwerlyp', 'hhelp'), // false
does_a_contain_b('ahwerlyp', 'hype'), // true
does_a_contain_b('ahwerlyp', 'foobar') // false
);
Please replace your code with this code:
<?php
$example = "ahwerlyp";
$findword = "help";
if (!array_diff(str_split($findword), str_split($example))) {
echo "exists";
} else {
echo "not exist";
}
?>
I have an array like below:
$fruits = array("apple","orange","papaya","grape")
I have a variable like below:
$content = "apple";
I need to filter some condition like: if this variable matches at least one of the array elements, do something. The variable, $content, is a bunch of random characters that is actually one of these available in the array data like below:
$content = "eaplp"; // it's a dynamically random char from the actual word "apple`
what have I done was like the below:
$countcontent = count($content);
for($a=0;$a==count($fruits);$a++){
$countarr = count($fruits[$a]);
if($content == $fruits[$a] && $countcontent == $countarr){
echo "we got".$fruits[$a];
}
}
I tried to count how many letters these phrases had and do like if...else... when the total word in string matches with the total word on one of array data, but is there something that we could do other than that?
We can check if an array contains some value with in_array. So you can check if your $fruits array contains the string "apple" with,
in_array("apple", $fruits)
which returns a boolean.
If the order of the letters is random, we can sort the string alphabetically with this function:
function sorted($s) {
$a = str_split($s);
sort($a);
return implode($a);
}
Then map this function to your array and check if it contains the sorted string.
$fruits = array("apple","orange","papaya","grape");
$content = "eaplp";
$inarr = in_array(sorted($content), array_map("sorted", $fruits));
var_dump($inarr);
//bool(true)
Another option is array_search. The benefit from using array_search is that it returns the position of the item (if it's found in the array, else false).
$pos = array_search(sorted($content), array_map("sorted", $fruits));
echo ($pos !== false) ? "$fruits[$pos] found." : "not found.";
//apple found.
This will also work but in a slightly different manner.
I split the strings to arrays and sort them to match eachoter.
Then I use array_slice to only match the number of characters in $content, if they match it's a match.
This means this will match in a "loose" way to with "apple juice" or "apple curd".
Not sure this is wanted but figured it could be useful for someone.
$fruits = array("apple","orange","papaya","grape","apple juice", "applecurd");
$content = "eaplp";
$content = str_split($content);
$count = count($content);
Foreach($fruits as $fruit){
$arr_fruit = str_split($fruit);
// sort $content to match order of $arr_fruit
$SortCont = array_merge(array_intersect($arr_fruit, $content), array_diff($content, $arr_fruit));
// if the first n characters match call it a match
If(array_slice($SortCont, 0, $count) == array_slice($arr_fruit, 0, $count)){
Echo "match: " . $fruit ."\n";
}
}
output:
match: apple
match: apple juice
match: applecurd
https://3v4l.org/hHvp3
It is also comparable in speed with t.m.adams answer. Sometimes faster sometimes slower, but note how this code can find multiple answers. https://3v4l.org/IbuuD
I think this is the simplest way to answer that question. some of the algorithm above seems to be "overkill".
$fruits = array("apple","orange","papaya","grape");
$content = "eaplp";
foreach ($fruits as $key => $fruit) {
$fruit_array = str_split($fruit); // split the string into array
$content_array = str_split($content); // split the content into array
// check if there's no difference between the 2 new array
if ( sizeof(array_diff($content_array, $fruit_array)) === 0 ) {
echo "we found the fruit at key: " . $key;
return;
}
}
What about using only native PHP functions.
$index = array_search(count_chars($content), array_map('count_chars', $fruits));
If $index is not null you will get the position of $content inside $fruits.
P.S. Be aware that count_chars might not be the fastest approach to that problem.
With a random token to search for a value in your array, you have a problem with false positives. That can give misleading results depending on the use case.
On search cases, for example wrong typed words, I would implement a filter solution which produces a matching array. One could sort the results by calculating the levenshtein distance to fetch the most likely result, if necessary.
String length solution
Very easy to implement.
False positives: Nearly every string with the same length like apple and grape would match.
Example:
$matching = array_filter($fruits, function ($fruit) use ($content) {
return strlen($content) == strlen($fruit);
});
if (count($matching)) {
// do your stuff...
}
Regular expression solution
It compares string length and in a limited way containing characters. It is moderate to implement and has a good performance on big data cases.
False positives: A content like abc would match bac but also bbb.
Example:
$matching = preg_grep(
'#['.preg_quote($content).']{'.strlen($content).'}#',
$fruits
);
if (count($matching)) {
// do your stuff...
}
Alphanumeric sorting solution
Most accurate but also a slow approach concerning performance using PHP.
False positives: A content like abc would match on bac or cab.
Example:
$normalizer = function ($value) {
$tokens = str_split($value);
sort($tokens);
return implode($tokens);
};
$matching = array_filter($fruits, function ($fruit) use ($content, $normalizer) {
return ($normalizer($fruit) == $normalizer($content));
});
if (count($matching)) {
// do your stuff...
}
Here's a clean approach. Returns unscrambled value early if found, otherwise returns null. Only returns an exact match.
function sortStringAlphabetically($stringToSort)
{
$splitString = str_split($stringToSort);
sort($splitString);
return implode($splitString);
}
function getValueFromRandomised(array $dataToSearch = [], $dataToFind)
{
$sortedDataToFind = sortStringAlphabetically($dataToFind);
foreach ($dataToSearch as $value) {
if (sortStringAlphabetically($value) === $sortedDataToFind) {
return $value;
}
}
return null;
}
$fruits = ['apple','orange','papaya','grape'];
$content = 'eaplp';
$dataExists = getValueFromRandomised($fruits, $content);
var_dump($dataExists);
// string(5) "apple"
Not found example:
$content = 'eaplpo';
var_dump($dataExists);
// NULL
Then you can use it (eg) like this:
echo !empty($dataExists) ? $dataExists . ' was found' : 'No match found';
NOTE: This is case sensitive, meaning it wont find "Apple" from "eaplp". That can be resolved by doing strtolower() on the loop's condition vars.
How about looping through the array, and using a flag to see if it matches?
$flag = false;
foreach($fruits as $fruit){
if($fruit == $content){
$flag = true;
}
}
if($flag == true){
//do something
}
I like t.m.adams answer but I also have a solution for this issue:
array_search_random(string $needle, array $haystack [, bool $strictcase = FALSE ]);
Description: Searches a string in array elements regardless of the position of the characters in the element.
needle: the caracters you are looking for as a string
haystack: the array you want to search
strictcase: if set to TRUE needle 'mood' will match 'mood' and 'doom' but not 'Mood' and 'Doom', if set to FALSE (=default) it will match all of these.
Function:
function array_search_random($needle, $haystack, $strictcase=false){
if($strictcase === false){
$needle = strtolower($needle);
}
$needle = str_split($needle);
sort($needle);
$needle = implode($needle);
foreach($haystack as $straw){
if($strictcase === false){
$straw = strtolower($straw);
}
$straw = str_split($straw);
sort($straw);
$straw = implode($straw);
if($straw == $needle){
return true;
}
}
return false;
}
if(in_array("apple", $fruits)){
true statement
}else{
else statement
}
I have a comma separated list of prefixes stored in a variable
$prefixes = “fa,go,urg”;
and a word stored in another variable
$word = “good”;
Now I want to know efficient way to check if any of the prefixes stored in $prefixes is the prefix of $word or not.
My intention is
If any of the prefixes stored in $prefixes is the prefix of the word stored in $word return TRUE.
If none of the prefixes stored in $prefixes is the prefix of the word stored in $word return FALSE.
Note:- Comma separated list of prefixes is provide by user using text box.
One thing that can be done is to have the prefixes within an array, and then check if $word is present within the array $preArr using in_array
in_array
(PHP 4, PHP 5, PHP 7)
in_array — Checks if a value exists in an array
$prefixes = “fa,go,urg”;
$preArr = explode(',', $prefixes); // Convert to array
$word = “good”;
if (in_array($word, $preArr)) {
echo "Success!";
} else {
echo "Failure!";
}
The substr function can achieve the desired result. It checks for the word good in the prefixes at specified location, which is the beginning of the word.
From the PHP Manual:
substr — Return part of a string
Description
string substr ( string $string , int $start [, int $length ] )
Returns the portion of string specified by the start and length parameters.
Try this:
$prefixes = “fa,go,urg”;
$word = “good”;
$Arr[] = explode(',', $prefixes); // Convert to array
$elements = count($Arr[]); //get total elements in array
for ($i=0;$i<count;$i++) {
if (substr( $Arr(i), 0, 4 ) === $word) {
return true;
}
else {return false;}
}
Your problem can be solved by a few ways, the most programmatic method being to just do a simple check, iterate across $prefixes and check it against 0.....i where i = N - 1 and N = count($prefixes[$i])
function inPrefixArr($prefixes, $word) {
$prefixesInArray = explode(',', $prefixes);
for ($i = 0; $i < count($prefixesInArray); i++) {
if (count($prefixesInArray[$i]) <= count($word)) {
if ($prefixesInArray[$i] == substr($word, 0, count($prefixesInArray[$i]))) {
return True;
}
}
}
return False
}
This checks if the any of the prefixes are a prefix of the word given in O(mn) time where m is the max length of some prefix in the array given. It is also the fastest and most space optimal solution that can be found.
As it seems you weren't asking for a theoretical/CS question, there are other interesting ways to implement this in other data structures which can yield better runtimes if you do this repeatedly.
What I have so far:
$searchQuery = "keyword1 keyword2";
$searchArray = explode(" ", $searchQuery);
$stringToCheck = "keyword1 keyword3 keyword2";
foreach ($searchArray as $searchKeyword) {
if (strpos($stringToCheck, $searchKeyword) !== false) :
//do something
endif;
}
endif;
What I want is to display something only if ALL values in the search query are found in a string. With my current code above, if the string contains keyword1 and keyword2, it "does something" twice, once for each match. It also comes up as true if the string only contains keyword1 but not keyword2, in that case it displays the content once.
Solution
function str_contains_all($haystack, array $needles) {
foreach ($needles as $needle) {
if (strpos($haystack, $needle) === false) {
return false;
}
}
return true;
}
Usage:
$haystack = 'foo, bar, baz';
$needles = array('foo', 'bar', 'baz');
if (str_contains_all($haystack, $needles)) {
echo "Success\n";
// ...
}
Notes
Since you specified that you only wish to perform an action when the "haystack" string contains all the substring "needles", it is safe to return false as soon as you discover a needle that is not in the haystack.
Other
Using if (...): /* ... */ endif; is fairly uncommon in PHP from my experience. I think most developers would prefer the C-style if (...) { /* ... */ } syntax.
For anyone who might need another way. I came up with this while looking for a solution.
Ensure what's to be tested are both arrays;
$var1 = explode(' ',"a string to be turned to an array");
$var2 = ["test","a","string","array"];
Get the counts (or lengths) of both arrays;
$var1count = count($var1);
$var2count = count($var2);
//Get the intersection of both arrays with array_intersect() method
$intersect = array_intersect($var1,$var2);
//check if the count (or length) of the intersect is the same as the test var (eg $var1)
if(count($intersect)===$var1count)//it has all the words
FYI: case sensitive. You might want to convert all to lower or upper case
I am parsing domains and running into a problem handling subdomains. If the domain is http://www.google.co.uk, I want to obtain the length of google which is 6.
I am using parse_url() to return the host in this case www.google.co.uk like so.
$url = 'http://www.google.co.uk';
$info = parse_url($url);
// remove www. and return google.co.uk
$new = str_replace('www.','',$info['host']);
$pieces = explode(".", $new);
$len = strlen($pieces[0]); // returns character length of google = 6
echo $len;
My code doesn't work if the domain contains a subdomain like http://test.google.co.uk: it returns a length of 4; I expect it to return a length of 6.
Any ideas?
Output is correct. when input is http://test.google.co.uk value of parse_url('http://test.google.co.uk')['host'] is http://test.google.co.uk. When you will exploce this string on dot first element of array will be test and its length is 4.
To get google instead of test you need to replace subdomain with nothing as you did in your first example or take the second element in exploded string. E.g:
$url = 'http://test.google.co.uk';
$info = parse_url($url);
$pieces = explode(".", $info['host']);
$len = strlen($pieces[1]); // returns character length of google = 6
echo $len;
There is not other way than collect and hardcode all known public 2-nd level zones (like co.uk, com.ua, co.tw and so on) and filter them in your code. Be aware to detect test.example.ua as test becouse both example.com.ua and example.ua are valid domains (which is not a case with uk zone).
Your code may look like this:
function mainDomainLength($fullDomain) {
//$fullDomain = 'DOMAIN.co.uk';
$zones = array('uk' => array('co'), 'ua' => array('com', 'org'), ...);
$domainArray = explode('.', $fullDomain);
if (count($domain) > 2 && isset($zones[$domain[count($domain)-1]])) {
if (isset($zones[$domain[count($domain)-1]][$domain[count($domain)-2]])) {
return strlen($domain[count($domain)-3]);
}
} else if (count($domain) > 1) {
return strlen($domain[1]);
} else {
return strlen($domain[0]);
}
}
EDIT: By the way! Look at Get the second level domain of an URL (java). As I can understand there is the answer you need (and url to special domains collection collected be Mozilla).