How to use regular expression for calculator input with javascript? - javascript

I am trying to write simple calculator with JavaScript. I want to check if user input is correct or not. I wrote regular expression in order to make sure user input is proper but it is not working. What I want to do is a simple rule which is operator(/*-+) should be followed by operand(0-9) but first operator can be - or +. The regular expression below is not working. What is my mistake?
^[-+]?[0-9]{0,}([-+*/]?)[0-9]+$

Your expression looks for an optional - or + followed by zero or more digits ([0-9]{0,}). I think you probably wanted one or more (+). Similarly, the ? in ([-+*/]?) makes the operator optional. You probably also want to capture the various parts.
It is fine when I have something one operator between two operand but when I do 9+9+9 which is more then two it is not working.
If you want to allow additional operators and digits following them, you have to allow the latter part to repeat.
Here's my rough take:
^\s*([-+]?)(\d+)(?:\s*([-+*\/])\s*((?:\s[-+])?\d+)\s*)+$
Live Example (But there's something not quite right happening with the capture groups if you have three or more terms.)
Changes I made:
Use \d rather than [0-9] (\d stands for "digit")
Put the digits and the operators in capture groups.
Don't make the digits or operator optional.
Allow optional whitespace (\s*) in various places.
The (?: _________ )+ is what lets the part within those parens repeat.
Allow a - or + in front of the second group of digits, but only if preceded by a space after the operator.

^[-+]?
Is correct, but then
[0-9]{0,}
Is not, you want + quantifier as if you use {0,} (which is the same as *) you could have "+*9" being correct.
Then,
([-+*/]?)[0-9]+
Is wrong, you want :
([-+*/]+[-+]?[0-9]+)*
So you will have for instance *-523+4234/-34 (you can use an operand on an either negative or positive number, or not precised number which would mean obviously positive)
So finally, you would have something like :
^[-+]?[0-9]+([-+*/]+[-+]?[0-9]+)*$
Of course, you can replace class [0-9] with \d

Related

How to use regex ?: operator and get the right group in my case? [duplicate]

This is an example string:
123456#p654321
Currently, I am using this match to capture 123456 and 654321 in to two different groups:
([0-9].*)#p([0-9].*)
But on occasions, the #p654321 part of the string will not be there, so I will only want to capture the first group. I tried to make the second group "optional" by appending ? to it, which works, but only as long as there is a #p at the end of the remaining string.
What would be the best way to solve this problem?
You have the #p outside of the capturing group, which makes it a required piece of the result. You are also using the dot character (.) improperly. Dot (in most reg-ex variants) will match any character. Change it to:
([0-9]*)(?:#p([0-9]*))?
The (?:) syntax is how you get a non-capturing group. We then capture just the digits that you're interested in. Finally, we make the whole thing optional.
Also, most reg-ex variants have a \d character class for digits. So you could simplify even further:
(\d*)(?:#p(\d*))?
As another person has pointed out, the * operator could potentially match zero digits. To prevent this, use the + operator instead:
(\d+)(?:#p(\d+))?
Your regex will actually match no digits, because you've used * instead of +.
This is what (I think) you want:
(\d+)(?:#p(\d+))?

Detecting Number, Pi and e in String

I have a regex /(-?.?\d+(\.\d{1,2})?))/g to capture numbers that can be negative, decimal or positive. I also want to be able to capture special symbols, specifically πe.
What I have tried:
/(-?.?\d+(\.\d{1,2})?)|πe)/g
How can I capture these two symbols an expression such as 234π2, 43.1πe or 3π1e43e
I assume you use JS.
Just use this for (negative) numbers: /-?(\d*.)?(\d+)/
this for your symbols: /[πe]/
And now we combine those two to match multiples like 234π2.
/((-?(\d*.)?(\d+))|([πe]))+/
Fix
The pattern also matches -1-1-1 or .1.1.1 as pointed out by Casimir et Hippolyte. To fix this:
The first part will still be a number or symbol: /((-?(\d*\.)?\d+)|[πe])/.
But instead of simply using the expression repeatedly, we will use a new one that won't allow signs or decimals like .1: /(((\d+\.)?\d+)|[πe])/
Put together: /((-?(\d*\.)?\d+)|[πe])(((\d+\.)?\d+)|[πe])*/
(I also remove so unnecessary brackets.)
Here is a working regex that captures numbers, modifiers (presently +-.) and special chars in all strings and leaves the rest out. Note that your e may well capture inadvertent es in your text. For lack of other test cases this is the best that I could do.
[-+.]?[πe]?\d+[πe]?
the first part is an optional modifier (from that class, zero of more times)
and another optional class of special chars
your digits, one or more times
final optional class of special chars, zero or more times.

Regex for digits and hyphen only

I am trying to understand regex, for digits of length 10 I can simply do
/^[0-9]{10}$/
for hyphen only I can do
/^[-]$/
combining the two using group expression will result in
/^([0-9]{10})|([-])$/
This expression does not work as intended, it somehow will match part of the string instead of not match at all if the string is invalid.
How do I make the regex expression that accepts only "-" or 10 digits?
It would have worked fine to combine your two regexps exactly as you had them. In other words, just use the alternation/pipe operator to combine
/^[0-9]{10}$/
and
/^[-]$/
as is, directly into
/^[0-9]{10}$|^[-]$/
↑↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑ YOUR ORIGINAL REGEXPS, COMBINED AS IS WITH |
This can be represented as
and that would have worked fine. As others have pointed out, you don't need to specify the hyphen in a character class, so
/^[0-9]{10}$|^-$/
↑ SIMPLIFY [-] TO JUST -
Now, we notice that each of the two alternatives has a ^ at the beginning and a $ at the end. That is a bit duplicative, and it also makes it little harder to see immediately that the regexp is always matching things from beginning to end. Therefore, we can rewrite this, as explained in other answers, by taking the ^ and $ out of both sub-regexps, and combine their contents using the grouping operator ():
/^([0-9]{10}|-)$/
↑↑↑↑↑↑↑↑↑↑↑↑↑ GROUP REGEXP CONTENTS WITH PARENS, WITH ANCHORS OUTSIDE
The corresponding visualization is
That would also work fine, but you could use \d instead of [0-9], so the final, simplest version is:
/^(\d{10}|-)$/
↑↑ USE \d FOR DIGITS
and this visualizes as
If for some reason you don't want to "capture" the group, use (?:, as in
/^(?:\d{10}|-)$/
↑↑ DON'T CAPTURE THE GROUP
and the visualization now shows that group is not captured:
By the way, in your original attempt to combine the two regexps, I noticed that you parenthesized them as in
/^([0-9]{10})|([-])$/
↑↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑ YOU PARENTHESIZED THE SUB-REGEXPS
But actually this is not necessary, because the pipe (alternation, of "or") operator has low precedence already (actually it has the lowest precedence of any regexp operator); "low precedence" means it will apply only after things on both side are already processed, so what you wrote here is identical to
/^[0-9]{10}|[-]$/
which, however, still won't work for the reasons mentioned in other answers, as is clear from its visualization:
How do I make the regex expression that accepts only "-" or 10 digits?
You can use:
/^([0-9]{10}|-)$/
RegEx Demo
Your regex is just asserting presence of hyphen in the end due to misplacements of parentheses.
Here is the effective breakdown of OP's regex:
^([0-9]{10}) # matches 10 digits at start
| # OR
([-])$ # matches hyphen at end
which will cause OP's regex to match any input starting with 10 digits or ending with hyphen making these invalid inputs also a valid match:
1234567890111
1234----
------------------
1234567890--------
To get the regex expression that accepts only "-" or 10 digits - change your regexp as shown below:
^(\d{10}|-)$
DEMO link
The problem with your regex is it's looking for strings either
starting with 10 digits i.e. ^([0-9]{10}) or
ends with "-" - i.e. ([-])$
You needs an addtional wrapping ^( .. )$ to get this work. i.e.
/^(([0-9]{10})|([-]))$/
Better yet /^([0-9]{10}|-)$/ since [-] and - are both the same.

JavaScript - Regular Expression For Alpha/ Numeric combination

Pardon my inexperience in Regex world.
I am trying to validate a expression which look like this : AB-4567 or PK-1234.
i.e. either set of 2 fix letters followed by a '-' and then digits with no constrain on length.
Few more valid examples:
AB-1234
AB-12
AB-54643564
PK-1
PK-341313
PK-133
So, it should start with either AB or PK then without any space hyphen and then any length of digits
I tried with /(AB)|(PK)[-][0-9]/ but it fails in following situation
ABPK-1213 (both set of prefix)
AB-R12U45N (alphabets in digits. either at start, middle or end)
I know I am missing something very basic but not able to solve it.
For the first six examples
/^(AB|PK)-[0-9]+$
If you want to include the other two possibility (ABPK-1213 , AB-R12U45N) try
/^(AB|PK|ABPK|PKAB)-[0-9A-Z]+$
You were almost there:
^(?:AB|PK)-[0-9]+$
Your alternation character | was in the wrong place. The way you had it, it meant "match AB OR match PK and all these other characters.

Regular Expression with optional elements in input string in javascript

Can anyone give me the regular expression for currency which have the following formats :
1000 - valid
1,000 - valid
1,000.00 or 1000.00 - valid.
This means, the number May or May Not contain a comma(,) separator every 3 digits.
The number May Or May Not contain a dot (.), and if it carries a dot(.) it should show atleast 1 number after the decimal place.
And lastly it should be numerical characters only. If I need to make my question clear kindly suggest.
/^\d{1,3}(?:(?:,\d{3})*|(?:\d{3})*)(?:\.\d{1,2})?$/
"Between one and three digits, then any number of groups of three digits prefixed by a comma or any number of groups of three digits not prefixed by said comma (disallowing a mix of the two kinds of groups), then an optional group of one or two digits prefixed by a dot."
Note: This regex assumes that you want to validate an entire string against the criteria outlined in your question. If you want to use it to find such numbers in a longer string, you will need to remove the ^ and $ from the beginning and end of the expression.
Something like so should work: (,?\d{3})+(\.\d{2})?. The regex will attempt to match a sequence of 3 digits precedeed by an optional comma, which is then, finally followed by an optional decimal point and 2 digits.
Please refer to this tutorial for more information.
EDIT: As per the comment below, the above regex can fail. I would recommend first using this regular expression: ^[\d][\d.,]+$ to make sure that you only have digits, thousand and decimal seperators. This regular expression will also make sure that the number starts with a digit, not with anything else. You could most likely have one regular expression which does everything, but it will most likely be quite complex.

Categories

Resources