Regular Expression to match dates in YYYY-MM-DD format - php

I have a regular expression in PHP that looks for the date in the format of YYYY-MM-DD
What I have is: [\d]{4}-[\d]{2}-[\d]{2}
I'm using preg_match to test the date, the problem is that 2009-11-10 works, but 2009-11-1033434 works as well. It's been awhile since I've done regex, how do I ensure that it stops at the correct spot? I've tried doing /([\d]{4}-[\d]{2}-[\d]{2}){1}/, but it returns the same result.
Any help would be greatly appreciated.

What you need is anchors, specifically ^ and $. The former matches the beginning of the string, the latter matches the end.
The other point I would make is the [] are unnecessary. \d retains its meaning outside of character ranges.
So your regex should look like this: /^\d{4}-\d{2}-\d{2}$/.

^20[0-2][0-9]-((0[1-9])|(1[0-2]))-([0-2][1-9]|3[0-1])$
I added a little extra check to help with the issue of MM and DD getting mixed up by the user. This doesn't catch all date mixups, but does keeps the YYYY part between 2000 and 2029, the MM between 01 and 12 and the DD between 01 and 31

How do you expect your date to be terminated ?
If an end-of-line, then a following $ should do the trick.
If by a non-digit character, then a following negative assertion (?!\d) will similarly work.

you're probably wanting to put anchors on the expression.
i.e.
^[\d]{4}-[\d]{2}-[\d]{2}$
note the caret and dollar sign.

You probably want look ahead assertions (assuming your engine supports them, php/preg/pcre does)
Look ahead assertions (or positive assertions) allow you to say "and it should be followed by X, but X shouldn't be a part of the match). Try the following syntax
\d{4}-\d{2}-\d{2}(?=[^0-9])
The assertion is this part
(?=[^0-9])
It's saying "after my regex, the next character can't be a number"
If that doesn't get you what you want/need, post an example of your input and your PHP code that's not working. Those two items can he hugely useful in debugging these kinds of problems.

[\d]{4}-[\d]{2}-[\d]{2}?
where the question mark means "non-greedy"

You could try putting both a '^' and a '$' symbol at the start and end of your expression:
/^[\d]{4}-[\d]{2}-[\d]{2}$/
which match the start and the end of the string respectively.

Related

Regex isn't working properly with PHP or not getting how to implement this

There is something really I couldn't understand is how can I check my previous match with the next character and set starting and ending character please guys help me.
Here is an Example of my string
..A..B..A...B.A.B
What I'm trying to do is starting of string:
1=> Check the first character is .. or A
2=> and the Second thing is String cannot be like this ..A..A it must be like ..A..B.. and sequence.
3=> Ending character must be .. or B and won't be A
However, I can match the first character like so ^([A]{1}|[.]{1,100}) But when I'm trying this same way with ending character it is not working and I'm not getting how to do the step 2.
Save my day guys. Thanks
Failed Regex: ^[\.{1,40}|A{1}]+(?!A)+(B)+(?!B)+(B|\.{1,40})$
This regex should match the description you've given:
^(?:\.+?)?(A\.+?B\.?|\.\.)+$
^ is the start of the string (or line if m modifier is used).
(?:\.+?)? is one or more ., but it optional.
A\.+B\.? is looking for an A any amount of .s then a B and an optional ..
| is an alternative pattern we'll look at
\.\. are 2 .s
+ allows for the whole group to occur once or more
$ is the end of the string (or line, again depends on modifier being used)
Demo: https://regex101.com/r/OUJxxc/3/ (Probably with a clearer description than I provided)

PHP Regex IF THEN pattern

I'm new to writing Regex patterns and I'm struggling to understand why the following line doesn't work.
/^(£)?[0-9]+(?(?=\.[0-9]{2}){0,1}(p)?|$)/
Note: I'm writing this in PHP
I want the code to find £3.10p, but not £3p. Essentially, the letter 'p' can't be allowed unless it is preceded with a decimal point and 2 digits.
EDIT: To clarify, the letter p can be used at the end of the string, however if the string contains a £ and/or a decimal point, the p must be preceded by the point and 2 digits.
More examples of valid inputs:
£3.50
350
£350
234p
Invalid input:
£2p
Could someone please fix this and explain where I've gone wrong here?
Thanks
If 0.50p is allowed, then you can do it like this:
^((£?[0-9]+)(?!p)|([0-9]+p?))?(?<!p)(\.[0-9]{2})?p?$
Regex saved with all your examples here: https://regex101.com/r/rE1bT9/3
Try this:
/^(?(?=£)(£\d+\.\d{2}p?|£\d+)|\d+p?)$/
You can test it here:
https://regex101.com/r/mG8kR0/1
It is unclear how your valid sample "234p" matches your rule "p is allowed if there are at least two digits and a point". However, in your question you are using positive lookahead, this seems an overhead here.
Your rule for p may be written as: (\.[0-9]{2}p?)
So over all, you just need: /^(£)?[0-9]+(\.[0-9]{2}p?)$/
And if you allow "234p" also, just make the period optional: /^(£)?[0-9]+(\.?[0-9]{2}p?)$/
Try it out here: http://www.regexr.com/
The latter regex gives positive feedback to all your valid samples, and it denies the invalid input. It is unclear what should happen if there are only two digits, and if it is important to catch some pieces, there should be more brackets.
How about:
/^(?:£?[0-9]+(?:\.[0-9]{2})?|[0-9]+p?)$)/

PHP - Find number between 2 Unicode characters

Simple problem but i sux at regular expressions so i need here ur help.
What do i need to type to find a number between two first signs: •
Find out its codes but it doenst help me much: http://www.fileformat.info/info/unicode/char/2022/index.htm
Do you know what should i type in for example preg_match function to make it work?
Example:
• 12345 • TESTTESTTEST
Example Output:
12345
Thanks in advance!
To match a specific Unicode code point, use \x{FFFF} where FFFF is the hexadecimal number of the code point you want to match. You can omit leading zeros in the hexadecimal number between the curly braces. Since \x by itself is not a valid regex token, \x{1234} can never be confused to match \x 1234 times. It always matches the Unicode code point U+1234. \x{1234}{5678} will try to match code point U+1234 exactly 5678 times.
Anyway, what you're probably looking for is something like this:
\x{2022} (\d*) \x{2022}
As for the (\d*) part, it basically means match any digit infinite times, and assign this bit of the pattern as a match (braces stand for capture groups)
Actually i found out a way to do it a bit easier.
I used preg_match() with $pattern = "/[0-9]{1,}/";
Huh xD

Quick PHP regex for digit format

I just spent hours figuring out how to write a regular expression in PHP that I need to only allow the following format of a string to pass:
(any digit)_(any digit)
which would look like:
219211_2
so far I tried a lot of combinations, I think this one was the closest to the solution:
/(\\d+)(_)(\\d+)/
also if there was a way to limit the range of the last number (the one after the underline) to a certain amount of digits (ex. maximal 12 digits), that would be nice.
I am still learning regular expressions, so any help is greatly appreciated, thanks.
The following:
\d+_\d{1,12}(?!\d)
Will match "anywhere in the string". If you need to have it either "at the start", "at the end" or "this is the whole thing", then you will want to modify it with anchors
^\d+_\d{1,12}(?!d) - must be at the start
\d+_\d{1,12}$ - must be at the end
^\d+_\d{1,12}$ - must be the entire string
demo: http://regex101.com/r/jG0eZ7
Explanation:
\d+ - at least one digit
_ - literal underscore
\d{1,12} - between 1 and 12 digits
(?!\d) - followed by "something that is not a digit" (negative lookahead)
The last thing is important otherwise it will match the first 12 and ignore the 13th. If your number happens to be at the end of the string and you used the form I originally had [^\d] it would fail to match in that specific case.
Thanks to #sln for pointing that out.
You don't need double escaping \\d in PHP.
Use this regex:
"/^(\d+)_(\d{1,12})$/"
\d{1,12} will match 1 to 12 digist
Better to use line start/end anchors to avoid matching unexpected input
Try this:
$regex= '~^/(\d+)_(\d+)$~';
$input= '219211_2';
if (preg_match($regex, $input, $result)) {
print_r($result);
}
Just try with following regex:
^(\d+)_(\d{1,12})$

regexp to match xxx.xxx.xxx?

I need to check input with preg_match, which must be of this format: xxx.xxx.xxx
The number of block can vary... These are all examples of valid inputs:
001
00a.00a
0fg.001
aaa.aaa.001
001.001.002.001.001.001
Well I could probably write a regexp something like:
^([\da-z]{3}\.?)+$
But here comes the problem with the quantifier of the period. I mean if I use '?' to match 0 or 1 times, it would also match even if skip the dots somewhere, eg:
000.001.0010az001
then, if I used {1} to match one time, it would match nothing, because the last block does not have a dot.
So I can't think what to think of... Please advice
You can use:
^[\da-z]{3}(?:\.[\da-z]{3})*$
/^(?:[\da-z]{3}\.)*[\da-z]{3}$/

Categories