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
:)
Related
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!';
}
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 #!
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>";
I was wondering how I could check a string broken into an array against a preg_match to see if it started with www. I already have one that check for http://www.
function isValidURL($url)
{
return preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $url);
}
$stringToArray = explode(" ",$_POST['text']);
foreach($stringToArray as $key=>$val){
$urlvalid = isValidURL($val);
if($urlvalid){
$_SESSION["messages"][] = "NO URLS ALLOWED!";
header("Location: http://www.domain.com/post/id/".$_POST['postID']);
exit();
}
}
Thanks!
Stefan
You want something like:
%^((https?://)|(www\.))([a-z0-9-].?)+(:[0-9]+)?(/.*)?$%i
this is using the | to match either http:// or www at the beginning. I changed the delimiter to % to avoid clashing with the |
John Gruber of Daring Fireball has posted a very comprehensive regex for all types of URLs that may be of interest. You can find it here:
http://daringfireball.net/2010/07/improved_regex_for_matching_urls
I explode the string at first as the url might be half way through it e.g. hello how are you www.google.com
Explode the string and use a foreach statement.
Eg:
$string = "hello how are you www.google.com";
$string = explode(" ", $string);
foreach ($string as $word){
if ( (strpos($word, "http://") === 0) || (strpos($word, "www.") === 0) ){
// Code you want to excute if string is a link
}
}
Note you have to use the === operator because strpos can return, will return a 0 which will appear to be false.
I used this below which allows you to detect url's anywhere in a string. For my particular application it's a contact form to combat spam so no url's are allowed. Works very well.
Link to resource: https://css-tricks.com/snippets/php/find-urls-in-text-make-links/
My implementation;
<?php
// Validate message
if(isset($_POST['message']) && $_POST['message'] == 'Include your order number here if relevant...') {
$messageError = "Required";
} else {
$message = test_input($_POST["message"]);
}
if (strlen($message) > 1000) {
$messageError = "1000 chars max";
}
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
if (preg_match($reg_exUrl, $message)) {
$messageError = "Url's not allowed";
}
// Validate data
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
Try implode($myarray, '').strstr("www.")==0. That implodes your array into one string, then checks whether www. is at the beginning of the string (index 0).
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)) { }