Unknown modifier '(' when using preg_match() with a REGEX expression [duplicate] - php

This question already has answers here:
Warning: preg_replace(): Unknown modifier
(3 answers)
Closed 3 years ago.
I'm trying to validate dates like DD/MM/YYYY with PHP using preg_match(). This is what my REGEX expression looks like:
$pattern = "/^([123]0|[012][1-9]|31)/(0[1-9]|1[012])/(19[0-9]{2}|2[0-9]{3})$/";
But using it with a correct value, I get this message:
preg_match(): Unknown modifier '('
Complete code:
$pattern = "/^([123]0|[012][1-9]|31)/(0[1-9]|1[012])/(19[0-9]{2}|2[0-9]{3})$/";
$date = "01/03/2011";
if(preg_match($pattern, $date)) return TRUE;
Thank you in advance

Escape the / characters inside the expression as \/.
$pattern = "/^([123]0|[012][1-9]|31)\/(0[1-9]|1[012])\/(19[0-9]{2}|2[0-9]{3})$/";
As other answers have noted, it looks better to use another delimiter that isn't used in the expression, such as ~ to avoid the 'leaning toothpicks' effect that makes it harder to read.

You use / as delimiter and also in your expression. Now
/^([123]0|[012][1-9]|31)/
Is the "complete" expression and all following is expected as modifier, also the (.
You can simply use another delimiter.
~^([123]0|[012][1-9]|31)/(0[1-9]|1[012])/(19[0-9]{2}|2[0-9]{3})$~
Or you escape all occurence of / within the expression, but I would prefer another delimiter ;) Its more readable.

your delimiter is /, but you are using it inside the pattern itself.
Use a different delimiter, or escape the /

You could escape the slashes / as suggested. It'll eventually lead to the Leaning Toothpick Syndome, though.
It's common to use different delimiters to keep your regular expression clean:
// Using "=" as delimiter
preg_match('=^ ... / ... $=', $input);

checek date using below function
function checkDateFormat($date)
{
//match the format of the date
if (preg_match ("/^([0-9]{2}) \/([0-9]{2})\/([0-9]{4})$/", $date, $parts))
{
//check weather the date is valid of not
if(checkdate($parts[2],$parts[1],$parts[3]))
return true;
else
return false;
}
else
return false;
}
echo checkDateFormat("29/02/2008"); //return true
echo checkDateFormat("29/02/2007"); //return false

Related

Changing eregi in preg_match doesn't work [duplicate]

This question already has answers here:
How can I convert ereg expressions to preg in PHP?
(4 answers)
Closed 9 years ago.
I have this code in my PHP form :
function IsEmail($email)
{
$pattern = "^([a-z0-9_]|\\-|\\.)+#(([a-z0-9_]|\\-)+\\.)+[a-z]{2,7}$";
return (eregi($pattern,$email)) ? true : false;
};
And my local server gives me an error :
Function eregi() is deprecated
So I modified my code to :
function IsEmail($email)
{
$pattern = "^([a-z0-9_]|\\-|\\.)+#(([a-z0-9_]|\\-)+\\.)+[a-z]{2,7}$";
return (preg_match($pattern,$email)) ? true : false;
};
and now I get this error :
Warning: preg_match() [function.preg-match]: No ending delimiter '^' found
Any idea ?
You should begin the regexp with / and also end it with /.
Like:
$pattern = "/^([a-z0-9_]|\\-|\\.)+#(([a-z0-9_]|\\-)+\\.)+[a-z]{2,7}$/";
Add a delimiter.
$pattern = "/^([a-z0-9_]|\\-|\\.)+#(([a-z0-9_]|\\-)+\\.)+[a-z]{2,7}$/";
In this case I used / as delimiter. It occurs once at the beginning and once at the end.
Note that you have to escape the delimiter character if it occurs in the regex itselfs and should not act as a delimiter but as normal matching char. So every / in your regex has to be escaped to \/ (except the delimiters of course). But you don't have any inside your regex.

Wordpress Rewrite Rules Inspector plugin [duplicate]

This question already has answers here:
Warning: preg_replace(): Unknown modifier
(3 answers)
Closed 3 years ago.
preg_replace('/http:///ftp:///', 'https://', $value);
http:// and ftp:// inside $value should be replaced with https://
This code gives error:
preg_replace() [function.preg-replace]: Unknown modifier '/'
What is a true regex for this task?
Try using a different delimiter, say #:
preg_replace('#http://|ftp://#', 'https://', $value);
or (less recommended) escape every occurrence of the delimiter in the regex:
preg_replace('/http:\/\/|ftp:\/\//', 'https://', $value);
Also you are searching for the pattern http:///ftp:// which really does not make much sense, may be you meant http://|ftp://.
You can make your regex shorter as:
preg_replace('#(?:http|ftp)#', 'https', $value);
Understanding the error: Unknown modifier '/'
In your regex '/http:///ftp:///', the first / is considered as starting delimiter and the / after the : is considered as the ending delimiter. Now we know we can provide modifier to the regex to alter its default behavior. Some such modifiers are:
i : to make the matching case
insensitive
m : multi-line searching
But what PHP sees after the closing delimiter is another / and tries to interpret it as a modifier but fails, resulting in the error.
preg_replace returns the altered string.
$value = 'http://foo.com';
$value = preg_replace('#http://|ftp://#', 'https://', $value);
// $value is now https://foo.com
Use another delimiter character, like '#', for instance.
preg_replace('#/http://|ftp://#', 'https://', $value);
And do not confuse / and |
preg_replace('!(http://|ftp://)!', 'https://', $value);
Long story: Regexp needs to be enclosed in delimiters, and those have to be unique inside the whole regexp. If you want to use /, then the remaining /-s inside the regexp need to be escaped. This however makes the syntax look a bit ugly. Luckily you can use any character as delimiter. ! works fine, as will other characters.
The rest of the regexp just lists two options, either of which will be replaced with the second parameter.
preg_replace('|http:\/\/ftp:\/\/', 'https://|', $value);
Use this instead:
preg_replace('-(http|ftp)://-', 'https://', $value);
Or
preg_replace('/(http|ftp):\/\//', 'https://', $value);

How to convert this deprecated ereg() using pointer to preg_match() [duplicate]

This question already has answers here:
How can I convert ereg expressions to preg in PHP?
(4 answers)
Closed 3 years ago.
Using php 5.3 - ereg() deprecated...
I'm trying to convert this function (to preg_match), but I don't understand the "pointer"...
function gethostbyaddr_new($ip)
{
$output = `host -W 1 $ip`;
if (ereg('.*pointer ([A-Za-z0-9.-]+)\..*', $output, $regs))
{
return $regs[1];
}
return $ip;
}
pointer is just a bit of text to be matched
when I run host -W 1 I get
4.4.8.8.in-addr.arpa domain name pointer google-public-dns-b.google.com.
So you can use:
function gethostbyaddr_new($ip)
{
$output = `host -W 1 $ip`;
if (preg_match('/.*pointer ([A-Za-z0-9.-]+)\..*/', $output, $regs))
{
return $regs[1];
}
return $ip;
}
the first parameter of ereg is regular expression. So, .*pointer match anything (.*), then the word "pointer" (pointer), then the rest of expression.
Not much to it really. All you need to do is add a marker character to the start and end of the regex string.
Typically a marker character would be a slash (/), but it can be others (tilde ~ is used quite commonly and would work well for you here), as long as it's the same character at the start and end of the string, and doesn't appear within the string (you'd need to escape it with a backslash if it does).
So your code could look like this:
preg_match('~.*pointer ([A-Za-z0-9.-]+)\..*~', $output, $regs)
Note, if you use a slash as your regex marker character, you will need to double-it up, as slash is also an escape character in a PHP string.
In terms of explaining the actual expression:
.* - this is any number of any characters at the start of the string (you could actually leave this off this expression; it won't affect the matching)
pointer - this is looking for the actual word 'pointer' in the string being matched.
([A-Za-z0-9.-]+) - looks for one or more characters which are alpha-numeric or dot or hyphen. In addition, because these are enclosed in brackets, they become a 'matching group', which means that the result of this part of the search ends up in $regs[1].
\..* - looks for a dot character, followed by any number of any characters. As with the begining of the match, the .* can be dropped as it won't affect the matching.
So the whole expression is looking for a string which looks something like this:
blahblahblahpointer blah123-.blah.blahblahblah
and from that, you will get blah123-.blah in $regs[1].

Warning: preg_match() [function.preg-match]: Unknown modifier '(' [duplicate]

This question already has answers here:
Warning: preg_replace(): Unknown modifier
(3 answers)
Closed 3 years ago.
I have this HTML tags :
<div class="title">Copy me if you can</div>
so I wanna use preg_match to take just "Copy me if you can"
I'm using this preg pattern :
$preg = "<div class=\"title\">(.+?)</div>";
So I wrote this code
$match = preg_match($preg,$content);
The browser outputs :
Warning: preg_match() [function.preg-match]: Unknown modifier '('
What
You forgot the delimiter
$preg = '~<div class="title">(.+?)</div>~';
The first letter in the pattern always defines the delimiter to use. In your case its <, so the ending delimiter is >. Everything after that is used as special modifier, that changes specific behaviours. ( is not a valid modifier. Thats what the error message wanted to tell you :)
Try : $preg = '/<div class="title">([^<]+)</div>/';
Personally, when HTML is involved I'd steer away from the defacto delimiter / and use # instead so you don't have to remember to escape any closing HTML tags.
$preg = '#<div class="title">([^<]+)</div>#';
You need to add delimites to your regex. Try this:
$preg = "/<div class=\"title\">(.+?)<\/div>/";
/ are delimiters which marks the start and stop of your regex. The reason for delimiters is so that you can add flags to your regex. Those flags are inserted after your regex. Example:
$preg = "/<div class=\"title\">(.+?)<\/div>/i";
I've added i as a modifier, marking the regex search as case insensitive.
I have the same problem and wonder if I could do the same, ex.:
Warning: preg_match() [function.preg-match]: Unknown modifier 't' in /home/08/public/www/wp-content/plugins/woocommerce-gateway-dibs-form/gateway-dibs.php on line 707
This is the code:
if ( preg_match($_SERVER["REQUEST_URI"], 'woocommerce/dibscancel') !== false) {
header("HTTP/1.1 200 Ok");
$callback = new WC_Gateway_Dibs;
$callback->cancel_order(stripslashes_deep($_REQUEST));
return;
}

Unknown modifier '/' error in PHP [duplicate]

This question already has answers here:
Warning: preg_replace(): Unknown modifier
(3 answers)
Closed 3 years ago.
preg_replace('/http:///ftp:///', 'https://', $value);
http:// and ftp:// inside $value should be replaced with https://
This code gives error:
preg_replace() [function.preg-replace]: Unknown modifier '/'
What is a true regex for this task?
Try using a different delimiter, say #:
preg_replace('#http://|ftp://#', 'https://', $value);
or (less recommended) escape every occurrence of the delimiter in the regex:
preg_replace('/http:\/\/|ftp:\/\//', 'https://', $value);
Also you are searching for the pattern http:///ftp:// which really does not make much sense, may be you meant http://|ftp://.
You can make your regex shorter as:
preg_replace('#(?:http|ftp)#', 'https', $value);
Understanding the error: Unknown modifier '/'
In your regex '/http:///ftp:///', the first / is considered as starting delimiter and the / after the : is considered as the ending delimiter. Now we know we can provide modifier to the regex to alter its default behavior. Some such modifiers are:
i : to make the matching case
insensitive
m : multi-line searching
But what PHP sees after the closing delimiter is another / and tries to interpret it as a modifier but fails, resulting in the error.
preg_replace returns the altered string.
$value = 'http://foo.com';
$value = preg_replace('#http://|ftp://#', 'https://', $value);
// $value is now https://foo.com
Use another delimiter character, like '#', for instance.
preg_replace('#/http://|ftp://#', 'https://', $value);
And do not confuse / and |
preg_replace('!(http://|ftp://)!', 'https://', $value);
Long story: Regexp needs to be enclosed in delimiters, and those have to be unique inside the whole regexp. If you want to use /, then the remaining /-s inside the regexp need to be escaped. This however makes the syntax look a bit ugly. Luckily you can use any character as delimiter. ! works fine, as will other characters.
The rest of the regexp just lists two options, either of which will be replaced with the second parameter.
preg_replace('|http:\/\/ftp:\/\/', 'https://|', $value);
Use this instead:
preg_replace('-(http|ftp)://-', 'https://', $value);
Or
preg_replace('/(http|ftp):\/\//', 'https://', $value);

Categories