Am creating a class that handles redirection to exterior locations. I created a method called isBlocked which returns a boolean result. This function works as follows:
It loops through the $_blocked variable and compares is the input string is found, it it is it returns true otherwise false. Bellow is the actual incase my explanation is not enough.
public static function isBlocked($location)
{
for($i = 0; $i < sizeof(self::$_blocked); $i++)
{
if(self::$_blocked[$i] === $location)
{
return true;
}
else
{
return false;
}
}
}
This works perfectly, the problem comes when for example, lets say "google.com" is on the list and the input is "www.google.com", it will return false. This is obvious since am using the identical operator ===.
Question is the following: Is there any function in PHP that work with URLS apart from url_encode & url_decode? I obviously can create a regular expression but let me know if there is any other approach to this.
Thanks in advance.
It occurs to me that the match is backwards, since it's a many to one, with the one matching a (sub)part of any in the stack. So, in that case we can use a strpos() (in lieu of a regular expression):
function find_reverse_match($needle, $haystack) {
$i = 0;
$c = count($haystack);
while ($i < $c) {
if (strpos($needle, $haystack[$i++]) !== false) {
return true;
}
}
return false;
}
http://codepad.viper-7.com/69ot4O
There is no php function to replace only first occurrence in a string, so preg_replace() and in_array() will do the job:
$blocked = array(
'www.google.com',
'yahoo.com'
);
var_dump( in_array( preg_replace( '/^www\./', '', 'google.com' ), preg_replace( '/^www\./', '', $blocked ) ) ); // true
var_dump( in_array( preg_replace( '/^www\./', '', 'www.yahoo.com' ), preg_replace( '/^www\./', '', $blocked ) ) ); // true
var_dump( in_array( preg_replace( '/^www\./', '', 'www.facebook.com' ), preg_replace( '/^www\./', '', $blocked ) ) ); // false
i just take example:
Php Search_Array using Wildcard
that wrote #JaredFarrish and adopt for this particular case:
<?php
function isBlocked($location)
{
$blocked = [
'google.com',
'www.google.com',
'play.google.com',
'developers.google.com',
];
$matches = preg_grep("/^(www)?$location$/", $blocked);
if (empty($matches)) {
return false;
} else {
return true;
}
}
print isBlocked('play.google.com'); // 1
print isBlocked('www.google.com'); // 1
print isBlocked('google.com'); // 1
print isBlocked('stackoverflow.com'); // 0
And the answer: you should write regular expression)
Is it possible for you to string replace the www.?
public static function isBlocked($location)
{
for($i = 0; $i < sizeof(self::$_blocked); $i++)
{
if(self::$_blocked[$i] === str_replace("www.","",$location))
{
return true;
}
return false;
}
}
Psuedo code.
NVM. Seem you said you can do expression
Maybe use
parse_url
http://php.net/manual/en/function.parse-url.php
Related
I am creating this array with the below code:
$ignored = array();
foreach(explode("\n", $_POST["ignored"]) as $ignored2) {
$ignored[] = $ignored2;
}
and i want to check if any item inside the array is LIKE a variable. I have this so far:
if(in_array($data[6], $ignored)) {
but I'm not sure what to do with the LIKE
in_array() doesn't provide this type of comparison. You can make your own function as follows:
<?php
function similar_in_array( $sNeedle , $aHaystack )
{
foreach ($aHaystack as $sKey)
{
if( stripos( strtolower($sKey) , strtolower($sNeedle) ) !== false )
{
return true;
}
}
return false;
}
?>
You can use this function as:
if(similar_in_array($data[6], $ignored)) {
echo "Found"; // ^-search ^--array of items
}else{
echo "Not found";
}
Function references:
stripos()
strtolower()
in_array()
Well, like is actually from SQL world.
You can use something like this:
$ignored = array();
foreach(explode("\n", $_POST["ignored"]) as $ignored2) {
$ignored[] = $ignored2;
if ( preg_match('/^[a-z]+$/i', $ignored2) ) {
//do what you want...
}
}
UPDATE: Well, I found this answer, may be it's what you need:
Php Search_Array using Wildcard
Here is a way to do it that can be customized fairly easily, using a lambda function:
$words = array('one','two','three','four');
$otherwords = array('three','four','five','six');
while ($word = array_shift($otherwords)) {
print_r(array_filter($words, like_word($word)));
}
function like_word($word) {
return create_function(
'$a',
'return strtolower($a) == strtolower(' . $word . ');'
);
}
http://codepad.org/yAyvPTIq
To add different checks, simply add more conditions to the return. To do it in a single function call:
while ($word = array_shift($otherwords)) {
print_r(find_like_word($word, $words));
}
function find_like_word($word, $words) {
return array_filter($words, like_word($word));
}
function like_word($word) {
return create_function(
'$a',
'return strtolower($a) == strtolower(' . $word . ');'
);
}
I want to check all brackets start and close properly and also check it is mathematical expression or not in given string.
ex :
$str1 = "(A1+A2*A3)+A5+(B3^B5)*(C1*((A3/C2)+(B2+C1)))"
$str2 = "(A1+A2*A3)+A5)*C1+(B3^B5*(C1*((A3/C2)+(B2+C1)))"
$str3 = "(A1+A2*A3)+A5++(B2+C1)))"
$str4 = "(A1+A2*A3)+A5+(B3^B5)*(C1*(A3/C2)+(B2+C1))"
In above Example $str1 and $str4 are valid string....
Please Help....
You'll need a kind of parser. I don't think you can handle this by a regular expression, because you have to check the amount and the order of parentheses and possible nested ones. This class below is quick PHP port of a Python based Math expression syntax validator of parentheses I found:
class MathExpression {
private static $parentheses_open = array('(', '{', '[');
private static $parentheses_close = array(')', '}', ']');
protected static function getParenthesesType( $c ) {
if(in_array($c,MathExpression::$parentheses_open)) {
return array_search($c, MathExpression::$parentheses_open);
} elseif(in_array($c,MathExpression::$parentheses_close)) {
return array_search($c, MathExpression::$parentheses_close);
} else {
return false;
}
}
public static function validate( $expression ) {
$size = strlen( $expression );
$tmp = array();
for ($i=0; $i<$size; $i++) {
if(in_array($expression[$i],MathExpression::$parentheses_open)) {
$tmp[] = $expression[$i];
} elseif(in_array($expression[$i],MathExpression::$parentheses_close)) {
if (count($tmp) == 0 ) {
return false;
}
if(MathExpression::getParenthesesType(array_pop($tmp))
!= MathExpression::getParenthesesType($expression[$i])) {
return false;
}
}
}
if (count($tmp) == 0 ) {
return true;
} else {
return false;
}
}
}
//Mathematical expressions to validate
$tests = array(
'(A1+A2*A3)+A5+(B3^B5)*(C1*((A3/C2)+(B2+C1)))',
'(A1+A2*A3)+A5)*C1+(B3^B5*(C1*((A3/C2)+(B2+C1)))',
'(A1+A2*A3)+A5++(B2+C1)))',
'(A1+A2*A3)+A5+(B3^B5)*(C1*(A3/C2)+(B2+C1))'
);
// running the tests...
foreach($tests as $test) {
$isValid = MathExpression::validate( $test );
echo 'test of: '. $test .'<br>';
var_dump($isValid);
}
Well I suppose that the thing, you are looking for, is some Context-free grammar or Pushdown automaton. It can not be done only using regular expressions. (at least there is no easy or nice way)
That is because you are dealing with nested structures. Some idea of an implementation can be found here Regular expression to detect semi-colon terminated C++ for & while loops
Use Regular Expression that returns you howmany Opening Brackets and Closing Brackets are there?
then check for the number of both braces....if it is equal then your expression is right otherwise wrong...
I've been looking for a way to check if any of an array of values exists in a string, but it seems that PHP has no native way of doing this, so I've come up with the below.
My question - is there a better way of doing this, as this seems pretty inefficient? Thanks.
$match_found = false;
$referer = wp_get_referer();
$valid_referers = array(
'dd-options',
'dd-options-footer',
'dd-options-offices'
);
/** Loop through all referers looking for a match */
foreach($valid_referers as $string) :
$referer_valid = strstr($referer, $string);
if($referer_valid !== false) :
$match_found = true;
continue;
endif;
endforeach;
/** If there were no matches, exit the function */
if(!$match_found) :
return false;
endif;
Try with following function:
function contains($input, array $referers)
{
foreach($referers as $referer) {
if (stripos($input,$referer) !== false) {
return true;
}
}
return false;
}
if ( contains($referer, $valid_referers) ) {
// contains
}
What about this:
$exists = true;
array_walk($my_array, function($item, $key) {
$exists &= (strpos($my_string, $item) !== FALSE);
});
var_dump($exists);
This will check if any of the array values exists in the string. If only one is missing, You are given a false response. Should You need to find out which one are not present in the string, try this:
$exists = true;
$not_present = array();
array_walk($my_array, function($item, $key) {
if(strpos($my_string, $item) === FALSE) {
$not_present[] = $item;
$exists &= false;
} else {
$exists &= true;
}
});
var_dump($exists);
var_dump($not_present);
First of, alternate syntax is nice to use, but historically it's used in template files. Since it's structure is easily readable while coupling/decouping the PHP interpreter to interpolate HTML data.
Second, it's generally wise if all your code does is to check something, to immediately return if that condition is met:
$match_found = false;
$referer = wp_get_referer();
$valid_referers = array(
'dd-options',
'dd-options-footer',
'dd-options-offices'
);
/** Loop through all referers looking for a match */
foreach($valid_referers as $string) :
$referer_valid = strstr($referer, $string);
if($referer_valid !== false) :
$match_found = true;
break; // break here. You already know other values will not change the outcome
endif;
endforeach;
/** If there were no matches, exit the function */
if(!$match_found) :
return false;
endif;
// if you don't do anything after this return, it's identical to doing return $match_found
Now as specified by some of the other posts in this thread. PHP has a number of functions that can help. Here's a couple more:
in_array($referer, $valid_referers);// returns true/false on match
$valid_referers = array(
'dd-options' => true,
'dd-options-footer' => true,
'dd-options-offices' => true
);// remapped to a dictionary instead of a standard array
isset($valid_referers[$referer]);// returns true/false on match
Ask if you have any questions.
I'm sure this is an easy solution - I wrote found this endswith function and thought I'd try the array_walk function instead of testing each string separately. I'd assumed that the result of the array_walk function would be false but it returns 1...How do I get it to test all the strings and return false if it didn't find a match? Thanks
class {
function endsWith($value,$key,$haystack)
{
$length = strlen($value);
if ($length == 0) {
return true;
}
return (substr($haystack, -$length) === $value);
}
function thing()
{
$email = "should#returnfalse.info";
$arr = array("#test.net","#test.org.uk","#test.co.uk","#test.com");
echo array_walk($arr,array($this,"endsWith"),$email);
}
}
The return value of array_walk is not determined by whatever the callback does; it only informs you if walking the entire array was completed successfully.
You may want to look into a few alternatives.
This will return the number of matching elements and will also serve as a boolean test, but it will evaluate every element no matter what:
echo count(array_filter($arr,array($this,"endsWith")));
This will stop evaluating elements with endsWith as soon as a match is detected and will return true if there is a match, false otherwise:
$self = $this;
// cast to int because false is printed as the empty string
echo (int)array_reduce($arr,
function($result, $v) use ($email, $self) {
return $result || $self->endsWith($v, null, $email);
},
false);
Try this
class {
function thing()
{
$email = "should#returnfalse.info";
$arr = array("#test.net","#test.org.uk","#test.co.uk","#test.com");
foreach ($arr as $domain) {
$length = strlen($value);
if ($length != 0) {
if (substr($email, -$length) === $domain) { echo $domain; break; }
}
}
}
}
array_walk() just iterates over the elements of an array and returns true, if it was able to do it. (echo casts boolea true to a string '1') Have a look at array_recude()
$that = $this; // Cannot access $this directly before PHP 5.4
var_dump(
array_reduce (
$arr,
function($result, item) use ($email, $that) { return $result || $that->endsWith($item, null /* not used anyway */, $email);},
false
)
);
Additional $key is not used and useless in endsWith().
If you want to apply a function to all values and return a single result you should use array_reduce.
As of PHP 5.3, you can use anonymous functions:
class {
function thing()
{
$email = "should#returnfalse.info";
$arr = array("#test.net","#test.org.uk","#test.co.uk","#test.com");
$match = '';
$found = false;
array_walk($arr,function($value) use (&$match, &$found, $email) {
$length = strlen($value);
if ($length == 0) {
$found = true;
return;
}
if (substr($email, -$length) === $value) {
$match = $value;
$found = true;
}
});
if ($found) {
echo 'Found match: ' . $match;
} else {
echo 'No match found :(';
}
}
}
Can someone help me with algorithm for finding the position of the first occurrence of any number in a string?
The code I found on the web does not work:
function my_offset($text){
preg_match('/^[^\-]*-\D*/', $text, $m);
return strlen($m[0]);
}
echo my_offset('[HorribleSubs] Bleach - 311 [720p].mkv');
The built-in PHP function strcspn() will do the same as the function in Stanislav Shabalin's answer when used like so:
strcspn( $str , '0123456789' )
Examples:
echo strcspn( 'That will be $2.95 with a coupon.' , '0123456789' ); // 14
echo strcspn( '12 people said yes' , '0123456789' ); // 0
echo strcspn( 'You are number one!' , '0123456789' ); // 19
HTH
function my_offset($text) {
preg_match('/\d/', $text, $m, PREG_OFFSET_CAPTURE);
if (sizeof($m))
return $m[0][1]; // 24 in your example
// return anything you need for the case when there's no numbers in the string
return strlen($text);
}
function my_ofset($text){
preg_match('/^\D*(?=\d)/', $text, $m);
return isset($m[0]) ? strlen($m[0]) : false;
}
should work for this. The original code required a - to come before the first number, perhaps that was the problem?
I can do regular expressions but I have to go into an altered state to
remember what it does after I've coded it.
Here is a simple PHP function you can use...
function findFirstNum($myString) {
$slength = strlen($myString);
for ($index = 0; $index < $slength; $index++)
{
$char = substr($myString, $index, 1);
if (is_numeric($char))
{
return $index;
}
}
return 0; //no numbers found
}
Problem
Find the first occurring number in a string
Solution
Here is a non regex solution in javascript
var findFirstNum = function(str) {
let i = 0;
let result = "";
let value;
while (i<str.length) {
if(!isNaN(parseInt(str[i]))) {
if (str[i-1] === "-") {
result = "-";
}
while (!isNaN(parseInt(str[i])) && i<str.length) {
result = result + str[i];
i++;
}
break;
}
i++;
}
return parseInt(result);
};
Example Input
findFirstNum("words and -987 555");
Output
-987