I have a regular expression that I use to test against user input that expects currency. This statement allows an optional dollar sign, allows optional commas (as long as they are correctly placed), and allows a single decimal point as long as it's followed by at least another number.
^\$?\d{1,3}(,?\d{3})*(\.\d{1,2})?$
Examples like
$12.12
0.34
12,000
12,000000
are all allowed by design. There is one however that doesn't match that I would like to. If a user wants to enter a number like .34 it must be proceeded by a zero. So 0.34 matches, but .34 doesn't.
Here's how I updated the statement to fix this.
^(\$?\d{1,3}(,?\d{3})*)?(\.\d{1,2})?$
I've made the entire statement before the decimal point a capturing group and made it optional. What I'm worried about now though, is that my entire regex statement enclosed by two capturing groups which are optional. I don't want a blank space to match this pattern and I think it will. Is there a better option for what I'm trying to accomplish?
Edit: My original statement doesn't match .12 The second updated statement does however, because the entire statement is wrapped in optional capturing groups, a blank space would match this pattern and that is not desired.
Your optional group is the correct way to proceed. Note that non-capturing groups that are only used to group sequences of subpatterns are more efficient when you do not have to access the captured subvalues later.
The only thing you really miss is to avoid matching an empty string. You may achieve it using a positive lookahead (?=.) or (?!$) negative lookahead:
^(?!$)(?:\$?\d{1,3}(?:,?\d{3})*)?(?:\.\d{1,2})?$
See the regex demo
Details
^ - start of string
(?!$) - no end of string right after the start of string
(?: - start of an optional non-capturing group
\$? - 1 or 0 $ symbols
\d{1,3} - 1 to 3 digits
(?:- start of a non-capturing group repeated 0+ sequences of
,? - 1 or 0 commas
\d{3} - 3 digits
)* - end of the non-capturing group
)? - end of the optional non-capturing group
(?:\.\d{1,2})? - an optional non-capturing group matching 1 or 0 sequences of
\. - a dot
\d{1,2} - 1 or 2 digits
$ - end of string.
You can use the "or" syntax |
^\$?(\d{1,3}(,?\d{3})*|0)(\.\d{1,2})?$
I would also suggest that you don't need to capture the inner groups of (,\d{3})*
^\$?(\d{1,3}(?:,?\d{3})*|0)(\.\d{1,2})?$
(\d{1,3}(?:,?\d{3})*|0) either an amount \d{1,3}(?:,?\d{3})* or 0
Related
I have an array of 5 numbers, I'd like to match as long as there are three of the same number and two of the same different number in the array, placement does not matter. Number sequences can be any random string of 5 numbers between 1 - 5.
Examples of matches would be:
33322
24422
52225
44111
54545
*basically any grouping of 2 and 3 of the same numbers needs to match.
Best I've come up with so far:
^([0-9])\1{2}|([0-9])\1{1}$
I am not so good with regex, any help would be greatly appreciated.
You can use
^(?=[1-5]{5}$)(?=.*(\d)(?:.*\1){2})(?=.*(?!\1)(\d).*\2)\d+$
^(?=.*(\d)(?:.*\1){2})(?=.*(?!\1)(\d).*\2)[1-5]{5}$
See the regex demo.
If you want to allow any digits, replace [1-5] with \d.
Details:
^ - start of string
(?=[1-5]{5}$) - there must be five digits from 1 to 5 till end of string (this lookahead makes non-matching strings fail quicker)
(?=.*(\d)(?:.*\1){2}) - a positive lookahead that requires any zero or more chars as many as possible, followed with a digit (captured into Group 1) and then two sequences of any zero or more chars as many as possible and the same digit as captured into Group 1 immediately to the right of the current location
(?=.*(?!\1)(\d).*\2) - a positive lookahead that requires any zero or more chars as many as possible, followed with a digit (captured into Group 2) that is not equal to the digit in Group 1, and then any zero or more chars as many as possible and the same digit as captured into Group 2 immediately to the right of the current location
\d+ - one or more digits
$ - end of string.
There are many ways to do that. One is to match the following regular expression.
^(?=([1-5]).*\1)(?=.+(?!\1)([1-5]).*\2)(?:\1|\2){5}$
The idea is as follows.
use a positive lookahead to match and save to capture group 1 the first digit and require it to appear at least twice;
use a positive lookahead to match and save to capture group 2 a digit that is different from the digit in capture group 1 and require it to appear at least twice;
match a five-character string that contains only the digits in the two capture groups.
Demo
The regular expression can be broken down as follows.
^ # match beginning of string
(?= # begin a positive lookahead
([1-5]) # match a digit 1-5 and save to capture group 1
.* # match zero or more characters
\1 # match the digit in capture group 1
) # end positive lookahead
(?= # begin a positive lookahead
.+ # match one or more characters
(?!\1) # next character is not the digit in capture group 1
([1-5]) # match a digit 1-5 and save to capture group 2
.* # match zero or more characters
\2 # match the digit in capture group 2
) # end positive lookahead
(?:\1|\2){5}$ # match a 5-character string comprised of the digits
# in the two capture groups
Here's a second expression that could be used:
^(?=([1-5])\1*(?!\1)([1-5])(?:\1*\2){1,2}\1*$).{5}$
Demo
Currently, on the project, they have a pattern [^0-9,] and it replaces (String.prototype.replace) everything that we don't need. Except it's not so great. We can add a comma to the start and to the end of the string.
What do I need and I can't do it no matter how hard I try)
first should be a number in the range 0-9
after the first number should be a comma (one comma) or a number or numbers (0-9)
at the end of the line shouldn't be a comma
Correct example,
1,2,3
Incorrect,
,,,,1,,2dgd,d,
1,2,3,
,1,2,,,3
UPD: The method String.prototype.replace() is used on the project.
I'll be grateful if you help me!
If the comma's are optional, maybe you need:
^\d+(?:,\d+)*$
See the online demo
^ - Start string ancor
\d+ - One or more digits.
(?:- Open non-capture group.
,\d+ - A comma followed but one or more digits.
)* - Close non-capture group and match zero or more times.
$ - End string ancor.
Edit:
If you actually want to clean a string, maybe you could use:
(\d+).*?(,(?=.*\d))|\D
See the online demo. Just make sure to replace by $1$2.
(\d+) - 1st Capture group with one or more digits.
.*? - Lazy match anything opto:
(,(?=.*\d)) - 2nd Capture group to match literal comma with a nested positive lookahead to ensure there is still a digit ahead.
| - Or:
\D - Anything other than digit.
const regexp = new RegExp(/(\d+).*?(,(?=.*\d))|\D/g);
const value = '1,2,3'.replace(regexp, '$1$2');
console.log(value)
This should work:
^[0-9]+(?:,[0-9]+)*$
Begins with a digit or a set of digits, followed by zero or more occurrences of a comma followed by one or more digits. Don't miss the start and end line anchors.
Demo
I am using below regular expression to validate money which works fine.
^\d{1,3}(,\d{3})*$
Now I want to add minimum amount also like minimum amount should be 20,000
Can anyone please help me out.
Fiddle: https://regexr.com/5h5bf
fiddle updated with correct expression
Reading the comments, I'm not sure if regex would be your way forward, yet you seem determined. It seems that you are looking to validate a comma-seperated string that needs to start at 20,000, where each second part of the number is 3 digits long. I came up with:
^(?:[2-9]\d|[1-9]\d\d|[1-9],\d{3})(?:,\d{3})+$
See the online demo
^ - Start string ancor.
(?: - Open 1st non-capture group.
[2-9]\d - A digit ranging from 2-9 followed by any digit.
| - Or.
[1-9]\d\d - A digit ranging from 1-9 followed by any two digits.
| - Or.
[1-9],\d{3} - A digit ranging from 1-9 followed by a comma and any three digits.
) - Close 1st non-capture group.
(?: - Open 2nd non-capture group.
,\d{3} - A comma followed by any three digits.
)+ - Close 2nd non-capture group and repeat at least once.
$ - End string ancor.
As an alternative you could also use lookaheads, e.g.:
^(?=.{6,})(?!1.{5}$)[1-9]\d?\d?(?:,\d{3})+$
See the online demo
^ - Start string ancor.
(?=.{6,} - Positive lookahead for at 6 or more characters.
(?!1.{5}$) - Negative lookahead for 1 followed by 5 characters till end string.
[1-9]\d?\d? - A digit ranging from 1-9 followed by two optional digits (you could also write [1-9]\d{0,2}).
(?: - Open 2nd non-capture group.
,\d{3} - A comma followed by any three digits.
)+ - Close non-capture group and repeat at least once.
$ - End string ancor.
I am trying to grab a digit (5) followed by a possible - or (space) proceeding a sequence of 3 digits, followed finally by a single digit. If the first group doesn't match at all, then only return the other sequences of digits.
^(5\-? ?)?(\d{3})(\d)$
This looks right to me and doesn't throw any errors, but it's giving the 5 back:
"5489" -> ()("548")("9")
Where I would actually not want this expression to return a match for this pattern.
So a quick search brought me to possessive expressions and a lot of articles about your ex. From what I'm reading, this looks like it should work:
^(5\-? ?)?+(\d{3})(\d)$
But Javascript does not like that as a regular expression.
Is there a way to do a greedy possessive capture group in Javascript, or simulate it in this situation?
You can simulate possessive quantifier functionality by taking advantage of lookaround qualities:
^(?=(...))\1
Regex:
^(?=((5\-? ?)?))\1(\d{3})(\d)$
Live demo
If you have a look at the ECMAScript 5 docs, you will see there is no support for possessive quantifiers.
You may use
^(?!5\d{3}$)(5-? ?)?(\d{3})(\d)$
See the regex demo. The (?!5\d{3}$) negative lookahead will fail a match at once if the string starts with 5 and then has 3 digits.
Details:
^ - start of string
(?!5\d{3}$) - there cannot be 5 and then 3 digits and the end of string immediately to the right of the current location
(5-? ?)? - an optional sequence of 5, then an optional - and then an optional space
(\d{3}) - 3 digits
(\d) - one digit
$ - end of string.
Excuse my ignorance but I really need help with this, I need this regex: [A-Za-z0-9]+\s?[A-Za-z0-9]+ (an username that allows a single whitespace in the middle, but not at the beginning or at the end.), but limiting the total amount of characters to minimum 3 and maximun 30.
I have tried to adapt this answer using negative lookaheads, but so far is not working.
It has to be a regex, it can't use jQuery or anything else.
You may use a positive lookahead here:
^(?=.{3,30}$)[A-Za-z0-9]+(?:\s[A-Za-z0-9]+)?$
See the regex demo.
Details:
^ - start of string
(?=.{3,30}$) - there can be 3 to 30 chars (other than linebreak, replace the . with [A-Za-z0-9\s] to be more specific)
[A-Za-z0-9]+ - 1+ alphanumeric chars
(?:\s[A-Za-z0-9]+)? - an optional (1 or 0) occurrences of a
\s - whitespace
[A-Za-z0-9]+ - 1+ alphanumeric symbols
$ - end of string.
You can use:
(?=^[A-Za-z0-9]+\s?[A-Za-z0-9]+$).{3,30}
See a demo on regex101.com. It will match:
username123 # this one
user name 123 # this one not (two spaces!)
user name123 # this one
u sername123 # this one
username123 # this one not (space in the beginning!)