Check if uri string matches any pattern in list [duplicate] - php

This question already has answers here:
Is there a PHP function that can escape regex patterns before they are applied?
(2 answers)
Closed 5 years ago.
I want to check if the current $uri_string matches any of these patterns
$uri_string = 'project/details/1258';
$uri_patterns = [
'project/foo/',
'project/bizz/',
];
foreach($uri_patterns as $pattern) {
if(preg_match('/' . $pattern. '/i', $uri_string) == 1) {
echo 'Is a match!';
}
}
so if at some point the $uri_string = 'project/foo/123/some-other-params'; then this sould match the 'project/foo/' pattern. How can I do this?

You need to escape the / slashes from your regex like:
$uri_string = 'project/details/1258';
$uri_patterns = [
'project/foo/',
'project/bizz/',
];
foreach($uri_patterns as $pattern) {
$pattern = preg_quote($pattern, '/');
if(preg_match("/$pattern/i", $uri_string) == 1) {
echo 'Is a match!';
}
}
This uses preg_quote() to escape the slashes.
Alternatively, you can use different delimiter for the regex, like #:
preg_match("#$pattern#i", $uri_string);
Or you can ignore regex completely and use string parsing functions like:
foreach($uri_patterns as $pattern) {
if(strpos($uri_string, $pattern) !== false) {
echo 'Is a match!';
}
}

I think you'll need to escape those forward slashes:
$uri_patterns = [
'project\/foo\/',
'project\/bizz\/',
];
Then for your match, use:
preg_match('/' . $pattern . '/i', $uri_string, $matches);
if (!empty($matches)) {
echo 'Is a match!';
}

Related

Check if a string contains the "\" [duplicate]

This question already has answers here:
How do you make a string in PHP with a backslash in it? [closed]
(3 answers)
Find the occurrence of backslash in a string
(3 answers)
Closed 3 years ago.
I am trying to see if the string contains \ and if i put it like this
$search4 = '\'; or like $search4 = "\"; it won't work as this is incorrect.
This is my search function
function Search($search, $string){
$position = strpos($string, $search);
if ($position == true){
return 'true';
}
else{
return 'false';
}}
And i am calling it like that echo Search($search4, $string);
You need to escape the \ by using 2 \. Because '\' is escaping the single quote and is giving you an error. The same will happend with double quotes.
http://php.net/manual/en/regexp.reference.escape.php
function Search($search, $string){
$position = strpos($string, $search);
if ($position == true){
return 'true';
}else{
return 'false';
}
}
$search = '\\';
print Search($search, "someString");

php preg_match extract args

Does anyone know how to get the int from this preg_match? It's only showing me the URI.
$uri = "/user/view/2";
$pattern = "/user/view/[0-9]+";
if(preg_match('#^' . $pattern . '$#', $uri, $matched)) {
print_r($matched);
}
else {
echo "No match!";
}
You have no capture group in your pattern. Change:
$pattern = "/user/view/[0-9]+";
To:
$pattern = "/user/view/([0-9]+)";
And it will be in $matched[1].
You can use T-Regx and go
pattern('^/user/view/[0-9]+$')->match($uri)
->forFirst(function (Match $match) {
$int = $match->group(1);
print_r($int);
})
->orReturn("No match!");
And you don't have to delimiter it with #!

Using 2 or more needles when using strpos [duplicate]

This question already has answers here:
Using an array as needles in strpos
(16 answers)
Closed 9 years ago.
Im running strpos on a <a> tag to see if it contains either one of two urls.
At the moment im using this bellow - how would i set it to check if - tumblr.com OR google.com were present ?
function find_excluded_url ($url) {
$find = "tumblr.com"; // OR GOOGLE.COM ....
$pos = strpos($url, $find);
if ($pos === false) {
return false;
} else {
return true;
}
}
// SET URL
$url = "<a href='http://tumblr.com/my_post' rel='nofollow'>This site</a>";
// CALL FUNC
$run_url = find_excluded_url($url);
if ($run_url == true) {
echo "URL - " . $url . "<br>";
}
You can't use two needles in strpos. But what you can do, is use it twice, with an or:
function find_excluded_url ($url) {
return (strpos($url, "tumblr.com")!==false) || (strpos($url, "google.com")!==false);
}
For more complicated searches, you might want to look into Regular Expressions. This would work:
$subject = 'blablabgoogle
balblabtumblrasd
blaasdgoogleadsad';
$pattern = '#(?:google\.com|tumblr\.com)#i';
$result = preg_match($pattern, $subject, $subpattern, PREG_OFFSET_CAPTURE);
if($result) echo 'Position: ' . $subpattern[0][1];
The performance of this (if performance is an issue for you) depends on how many search queries you have and how big your haystack is. Regular expressions come with a relatively big overhead, however, they only have to run over the text once. If you use strpos twice, this gets expensive with long strings. If performance is really an issue, you could also write your own strpos that goes character per character. I doubt, however, that this is necessary.
function find_excluded_url ($url, $searchURL) {
$pos = strpos($url, $searchURL);
if ($pos === false) {
return false;
} else {
return true;
}
}
// SET URL
$url = "<a href='http://tumblr.com/my_post' rel='nofollow'>This site</a>";
// CALL FUNC
$run_url = find_excluded_url($url, 'google.com');
if ($run_url == true)
echo "URL - " . $url . "<br>";
$run_url = find_excluded_url($url, 'tumblr.com');
if ($run_url == true)
echo "URL - " . $url . "<br>";

ereg/eregi replacement for PHP 5.3 [duplicate]

This question already has answers here:
How can I convert ereg expressions to preg in PHP?
(4 answers)
Closed 3 years ago.
I'm sorry to ask a question but I am useless when it comes to understanding regex code.
In a php module that I didn't write is the following function
function isURL($url = NULL) {
if($url==NULL) return false;
$protocol = '(http://|https://)';
$allowed = '([a-z0-9]([-a-z0-9]*[a-z0-9]+)?)';
$regex = "^". $protocol . // must include the protocol
'(' . $allowed . '{1,63}\.)+'. // 1 or several sub domains with a max of 63 chars
'[a-z]' . '{2,6}'; // followed by a TLD
if(eregi($regex, $url)==true) return true;
else return false;
}
Can some kind soul give me the replacement code for that with whatever is required to replace the eregi
Good question - this is needed when you upgrade to PHP 5.3, where ereg and eregi functions are deprecated. To replace
eregi('pattern', $string, $matches)
use
preg_match('/pattern/i', $string, $matches)
(the trailing i in the first argument means ignorecase and corresponds to the i in eregi - just skip in case of replacing ereg call).
But be aware of differences between the new and old patterns! This page lists the main differences, but for more complicated regular expressions you have to look in more detail at the differences between POSIX regex (supported by the old ereg/eregi/split functions etc.) and the PCRE.
But in your example, you are just safe to replace the eregi call with:
if (preg_match("%{$regex}%i", $url))
return true;
(note: the % is a delimiter; normally slash / is used. You have either to ensure that the delimiter is not in the regex or escape it. In your example slashes are part of the $regex so it is more convenient to use different character as delimiter.)
Palliative PHP 5.3 until you replace all deprecated functions
if(!function_exists('ereg')) { function ereg($pattern, $subject, &$matches = []) { return preg_match('/'.$pattern.'/', $subject, $matches); } }
if(!function_exists('eregi')) { function eregi($pattern, $subject, &$matches = []) { return preg_match('/'.$pattern.'/i', $subject, $matches); } }
if(!function_exists('ereg_replace')) { function ereg_replace($pattern, $replacement, $string) { return preg_replace('/'.$pattern.'/', $replacement, $string); } }
if(!function_exists('eregi_replace')) { function eregi_replace($pattern, $replacement, $string) { return preg_replace('/'.$pattern.'/i', $replacement, $string); } }
if(!function_exists('split')) { function split($pattern, $subject, $limit = -1) { return preg_split('/'.$pattern.'/', $subject, $limit); } }
if(!function_exists('spliti')) { function spliti($pattern, $subject, $limit = -1) { return preg_split('/'.$pattern.'/i', $subject, $limit); } }
Did you want a complete replacement to preg_match and eregi?
if(!filter_var($URI, FILTER_VALIDATE_URL))
{
return false;
} else {
return true;
}
Or for Email:
if(!filter_var($EMAIL, FILTER_VALIDATE_EMAIL))
{
return false;
} else {
return true;
}
eregi is depreciated in PHP you have to use preg_match
function isValidURL($url)
{
return preg_match('%^((https?://)|(www\.))([a-z0-9-].?)+(:[0-9]+)?(/.*)?$%i', $url);
}
if(isValidURL("http://google.com"))
{
echo "Good URL" ;
}
else
{
echo "Bad Url" ;
}
Please see http://php.net/manual/en/function.preg-match.php for more information
Thanks
:)

Php search string (with wildcards)

Is there a way to put a wildcard in a string? The reason why I am asking is because currently I have a function to search for a substring between two substrings (i.e grab the contents between "my" and "has fleas" in the sentence "my dog has fleas", resulting in "dog").
function get_string_between($string, $start, $end){
$string = " ".$string;
$ini = strpos($string,$start);
if ($ini == 0) return "";
$ini += strlen($start);
$len = strpos($string,$end,$ini) - $ini;
return substr($string,$ini,$len);
}
What I want to do is have it search with a wildcard in the string. So say I search between "%WILDCARD%" and "has fleas" in the sentence "My dog has fleas" - it would still output "dog".
I don't know if I explained it too well but hopefully someone will understand me :P. Thank you very much for reading!
This is one of the few cases where regular expressions are actually helpful. :)
if (preg_match('/my (\w+) has/', $str, $matches)) {
echo $matches[1];
}
See the documentation for preg_match.
wildcard pattern could be converted to regex pattern like this
function wildcard_match($pattern, $subject) {
$pattern = strtr($pattern, array(
'*' => '.*?', // 0 or more (lazy) - asterisk (*)
'?' => '.', // 1 character - question mark (?)
));
return preg_match("/$pattern/", $subject);
}
if string contents special characters, e.g. \.+*?^$|{}/'#, they should be \-escaped
don't tested:
function wildcard_match($pattern, $subject) {
// quotemeta function has most similar behavior,
// it escapes \.+*?^$[](), but doesn't escape |{}/'#
// we don't include * and ?
$special_chars = "\.+^$[]()|{}/'#";
$special_chars = str_split($special_chars);
$escape = array();
foreach ($special_chars as $char) $escape[$char] = "\\$char";
$pattern = strtr($pattern, $escape);
$pattern = strtr($pattern, array(
'*' => '.*?', // 0 or more (lazy) - asterisk (*)
'?' => '.', // 1 character - question mark (?)
));
return preg_match("/$pattern/", $subject);
}
Use a regex.
$string = "My dog has fleas";
if (preg_match("/\S+ (\S+) has fleas/", $string, $matches))
echo ($matches[1]);
else
echo ("Not found");
\S means any non-space character, + means one or more of the previous thing, so \S+ means match one or more non-space characters. (…) means capture the content of the submatch and put into the $matches array.
I agree that regex are much more flexible than wildcards, but sometimes all you want is a simple way to define patterns. For people looking for a portable solution (not *NIX only) here is my implementation of the function:
function wild_compare($wild, $string) {
$wild_i = 0;
$string_i = 0;
$wild_len = strlen($wild);
$string_len = strlen($string);
while ($string_i < $string_len && $wild[$wild_i] != '*') {
if (($wild[$wild_i] != $string[$string_i]) && ($wild[$wild_i] != '?')) {
return 0;
}
$wild_i++;
$string_i++;
}
$mp = 0;
$cp = 0;
while ($string_i < $string_len) {
if ($wild[$wild_i] == '*') {
if (++$wild_i == $wild_len) {
return 1;
}
$mp = $wild_i;
$cp = $string_i + 1;
}
else
if (($wild[$wild_i] == $string[$string_i]) || ($wild[$wild_i] == '?')) {
$wild_i++;
$string_i++;
}
else {
$wild_i = $mp;
$string_i = $cp++;
}
}
while ($wild[$wild_i] == '*') {
$wild_i++;
}
return $wild_i == $wild_len ? 1 : 0;
}
Naturally the PHP implementation is slower than fnmatch(), but it would work on any platform.
It can be used like this:
if (wild_compare('regex are * useful', 'regex are always useful') == 1) {
echo "I'm glad we agree on this";
}
If you insist to use a wildcard (and yes, PREG is much better) you can use the function
fnmatch.
ex:
if (fnmatch('my * has', $str)) { }

Categories