I'm relativly new to regular expressions but I managed to create a working expression to validate dates (without leap years, and assuming people enter a valid 30 or 31 digit for a month).
This is the expressen:
/^\d[1-31]{2}\-\d[1-12]{2}\-\d[1900-2009]{4}$/
But I would like to have a dynamic regular expression like:
$yearSpan = (date("Y") - 110)."-".date("Y");
/^\d[1-31]{2}\-\d[1-12]{2}\-\d[$yearSpan]{4}$/
When I try to use this expression it keeps telling me the compilation failed because a range out of order in character class.
I'm using this expression to validate dates of birth, and it would be nice not to update it every time a year passes by.
Any suggestions?
I think you should consider using some date/time functions for this purpose.
You're using the character classes in wrong way. [1-31], [1-12] and [1900-2009] will not check for the ranges you have in them. That's not how character classes work and hence that's not how you check for numeric ranges with regex.
A character class [a-r] matches any char from a to r. [a-rx] matches any character from a to r and the character x. Similarly, [1-39] matches any character from 1 to 3 and the character 9 - hence it matches one of 1,2,3 and 9 - and not any number from 1 to 39 as you intended it to.
[1-31]{2} matches two consecutive numbers (the last 1 is redundant), both in the range 1 to 3 - 33 is a valid match.
To match a number from 1 to 31, the correct regex is 0?[1-9]|[1-2][0-9]|3[0-1]. ('0?' takes care of zero padding as in 01-09-2009
For months: 0?[1-9]|1[0-2]
For year: 19[0-9]{2}|200[0-9]
And - is not a meta character outside character classes - you need not escape it.
The correct regex would be:
/^(0?[1-9]|[1-2][0-9]|3[0-1])-(0?[1-9]|1[0-2])-(19[0-9]{2}|200[0-9])$/
If you are not interested in capturing the values, you can write it as:
/^(?:0?[1-9]|[1-2][0-9]|3[0-1])-(?:0?[1-9]|1[0-2])-(?:19[0-9]{2}|200[0-9])$/
You can do it with PHP date and time functions
http://php.net/manual/en/function.checkdate.php
Related
:)
We would like to set a special condition (based on PHP Preg_match regular expression) to validates a number on our form.
That “number field” need, at first, only contain a max of 13 numbers (and only numbers. No letters or anything else).
The very first number need to be (only) “1” or “2” (not anything else)
The 4rd and 5rd number represent (the 2 numbers combinated) the “Month of birth” of someone, so the 4rd number need to be "0" or "1", and the 5rd need to be between "1" and "9".
Really appreciates if you can help us for that, to have the good “syntax” for the regular expression in PHP Preg_match to validates that field on our form! :)
Thanks to the community for your support and help!
Regards
Here is the literal regex pattern you have described to us:
^[12]\d{2}(?:0[1-9]|1[0-2])\d{8}$
Sample script:
$input = "1231212345678";
if (preg_match("/^[12]\d{2}(?:0[1-9]|1[0-2])\d{8}$/", $input)) {
echo "MATCH";
}
This regex pattern says to:
^ from the start of the string
[12] match 1 or 2 as the first digit
\d{2} then match any digits in the 2nd and 3rd position
(?:0[1-9]|1[0-2]) match 01, 02, ..., 12 as the two digit month
\d{8} then match any other 8 digits
$ end of string
I have these two regular expression
^(((98)|(\+98)|(0098)|0)(9){1}[0-9]{9})+$
^(9){1}[0-9]{9}+$
How can I combine these phrases together?
valid phone :
just start with : 0098 , +98 , 98 , 09 and 9
sample :
00989151855454
+989151855454
989151855454
09151855454
9151855454
You haven't provided what passes and what doesn't, but I think this will work if I understand correctly...
/^\+?0{0,2}98?/
Live demo
^ Matches the start of the string
\+? Matches 0 or 1 plus symbols (the backslash is to escape)
0{0,2} Matches between 0 and 2 (0, 1, and 2) of the 0 character
9 Matches a literal 9
8? Matches 0 or 1 of the literal 8 characters
Looking at your second regex, it looks like you want to make the first part ((98)|(\+98)|(0098)|0) in your first regex optional. Just make it optional by putting ? after it and it will allow the numbers allowed by second regex. Change this,
^(((98)|(\+98)|(0098)|0)(9){1}[0-9]{9})+$
to,
^(?:98|\+98|0098|0)?9[0-9]{9}$
^ this makes the non-grouping pattern optional which contains various alternations you want to allow.
I've made few more corrections in the regex. Use of {1} is redundant as that's the default behavior of a character, with or without it. and you don't need to unnecessarily group regex unless you need the groups. And I've removed the outer most parenthesis and + after it as that is not needed.
Demo
This regex
^(?:98|\+98|0098|0)?9[0-9]{9}$
matches
00989151855454
+989151855454
989151855454
09151855454
9151855454
Demo: https://regex101.com/r/VFc4pK/1/
However note that you are requiring to have a 9 as first digit after the country code or 0.
Hi i'm using laravel and I want to validate create a regex which will allow a specific format for duration (not time as this can exceed a 24 hr format). so for example 124hrs 30 mins and 24 secs would be represented as follows 124:30:24. But the first value can be over 1 character and a number, the second value needs be a colon, the third value needs to be 2 characters and a number, the fourth value needs to be a colon and the fifth value needs to be 2 characters and a numbers.
Any ideas how I can create an regex that will achieve this to insert into the following array?
$rules = array(
'duration' => 'required|regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/'
);
invalid examples:
alphacharacters e.g. qwerty
0:0:0
0:
0
1
30:211:211
30:2111:2111
a:d:d
asd
valid examples:
01:00:00
1:00:00
30:21:21
330:21:21
1330:21:21
11330:21:21
basically any amount of hours.
Give your examples this regex should suffice:
^\d+:\d{2}:\d{2}$
Demo: https://regex101.com/r/kO4xN2/2
\d is a number
+ is a quantifier meaning one or more of the preceding character (or group)
{} is an amount of characters to allow (you can give it a range as well)
^$ are anchors, so the string must be an exact match, if there is more content in the string this should be removed.
I've found this REGEXP:
^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$
It's useful to validate a date in this format:
yyyy-mm-dd
with "-" as separator. It's perfect for me except that I'd like to make this:
1970-1-1
valid too, so I'm looking for a modification to have the zero optional in month and day block as first char. Could you please provide me some help?
If you want to have an optional zero, you can this RegEx (edited version of your own):
^[0-9]{4}-((?:0)?[1-9]|1[0-2])-((?:0)?[1-9]|[1-2][0-9]|3[0-1])$
To make a character ( or a range) optional in RegEx, put it in a parenthesis followed by a question mark:
[a-z] is mandatory
([a-z])? is optional, with capturing group
(?:[a-z])? without capturing group, just optional
Read more on Capturing group in RegEx
You could use something like so: ^[0-9]{4}-(([1-9])|(0[1-9]|1[0-2]))-(([1-9])|(0[1-9]|[1-2][0-9]|3[0-1]))$.
An example is available here.
Use your current regex just make the 0 optional 0?
^[0-9]{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|3[0-1])$
DEMO
PHP already has a construct to extract dates; if you're using a regex to extract the date instead, "Now you have two problems"
PHP's DateTime::createFromFormat: "Returns new DateTime object formatted according to the specified format"
You can use it's d or j option to accept 1 or 2 digit days and it's m or n option to accept 1 or 2 digit months.
The format you'll want to use is: "Y-m-d"
Is there a function or a easy way to strip down phone numbers to a specific format?
Input can be a number (mobile, different country codes)
maybe
+4917112345678
+49171/12345678
0049171 12345678
or maybe from another country
004312345678
+44...
Im doing a
$mobile_new = preg_replace("/[^0-9]/","",$mobile);
to kill everything else than a number, because i need it in the format 49171 (without + or 00 at the beginning), but i need to handle if a 00 is inserted first or maybe someone uses +49(0)171 or or inputs a 0171 (needs to be 49171.
so the first numbers ALWAYS need to be countryside without +/00 and without any (0) between.
can someone give me an advice on how to solve this?
You can use
(?:^(?:00|\+|\+\d{2}))|\/|\s|\(\d\)
to match most of your cases and simply replace them with nothing. For example:
$mobile = "+4917112345678";
$mobile_new = preg_replace("/(?:^(?:00|\+|\+\d{2}))|\/|\s|\(\d\)/","",$mobile);
echo $mobile_new;
//output: 4917112345678
regex101 Demo
Explanation:
I'm making use of OR here, matching each of your cases one by one:
(?:^(?:00|\+|\+\d{2})) matches 00, + or + followed by two numbers at the beginning of your string
\/ matches a / anywhere in the string
\s matches a whitspace anywhere in the string (it matches the newline in the regex101 demo, but I suppose you match each number on its own)
\(\d\) matches a number enclosed in brackets anywhere in the string
The only case not covered by this regex is the input format 01712345678, as you can only take a guess what the country specific prefix can be. If you want it to be 49 by default, then simply replace each input starting with a single 0 with the 49:
$mobile = "01712345678";
$mobile_new = preg_replace("/^0/","49",$mobile);
echo $mobile_new;
//output: 491712345678
This pattern (49)\(?([0-9]{3})[\)\s\/]?([0-9]{8}) will split number in three groups:
49 - country code
3 digits - area code
8 digits - number
After match you can construct clean number just concatnating them by \1\2\3.
Demo: https://regex101.com/r/tE5iY3/1
If this not suits you then please explain more precisely what you want with test input and expected output.
I recommend taking a look at LibPhoneNumber by Google and its port for PHP.
It has support for many formats and countries and is well-maintained. Better not to figure this out yourself.
https://github.com/giggsey/libphonenumber-for-php
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
$usNumberProto = $phoneUtil->parse("+1 650 253 0000", "US");