RegExp - How to check for both parentheses in the string - javascript

I'd like to know how can I match text ONLY if there are both parentheses (starting and closing).
Currently, my RegExp is: ^1?\s?\(?\d{3}\)?[-\s]?\d{3}[-\s]?\d{4}$.
It checks for US valid numbers, however \(? and \)? makes the difference. It should match the text if there is 0 of them or 2.
Some tests:
1 555)555-5555 - false
555)-555-5555 - false
(555-555-5555 - false
Now, they all return the same result - true.
Here is the link to it:
https://regexr.com/3kjei (^ is because I have to select only one string without any line break, please remove 2 other strings from it so you can see it returns true. All of the strings in this link should return true, just check it so only one string is in the text editor).
Thank you

You may use
^(?:1\s?)?(?:\(\d{3}\)|\d{3})[-\s]?\d{3}[-\s]?\d{4}$
See the regex demo.
Note that ^1?\s? in your regex allow a single whitespace in the beginning, that is why I suggest ^(?:1\s?)? - an optional sequence starting with 1 that is optionally followed wih whitespace.
The \(?\d{3}\)? part is replaced with (?:\(\d{3}\)|\d{3}) - a non-capturing group that matches either (+3 digits+) or 3 digits (so, no (123 or 123)` can be matched).
Details
^ - start of string
(?:1\s?)? - 1 or 0 occurrences of 1 optionally followed with 1 whitespace char
(?:\(\d{3}\)|\d{3}) - either (, 3 digits, ) or just 3 digits
[-\s]? - an optional - or whitespace
\d{3} - 3 digits
[-\s]?- an optional - or whitespace
\d{4} - 4 digits
$ - end of string.

Why not in the portion of your regex that says \(?\d{3}\)? that you "or" it instead.
Eg. Replace it with something like this:
((\(\d{3}\))|\d{3})

Related

How do I enforce that certain characters must be present when there is an optional character before them?

I would like to capture a string that meets the criteria:
may be empty
if it is not empty it must have up to three digits (-> \d{1,3})
may be optionally followed by a uppercase letter ([A-Z]?)
may be optionally followed by a forward slash (i.e. /) (-> \/?); if it is followed by a forward slash it must have from one to three digits
(-> \d{1,3})
Here's a valid input:
35
35A
35A/44
Here's invalid input:
34/ (note the lack of a digit after '/')
I've come up with the following ^\d{0,3}[A-Z]{0,1}/?[1,3]?$ that satisfies conditions 1-3. How do I deal with 4 condition? My Regex fails at two occassions:
fails to match when there is a digit and a forward slash and a digit e.g .77A/7
matches but it shouldn't when there isa digit and a forward slash, e.g. 77/
You may use
/^(?:\d{1,3}[A-Z]?(?:\/\d{1,3})?)?$/
See the regex demo
Details
^ - start of string
(?:\d{1,3}[A-Z]?(?:\/\d{1,3})?)? - an optional non-capturing group:
\d{1,3} - one to three digits
[A-Z]? - an optional uppercase ASCII letter
(?:\/\d{1,3})? - an optional non-capturing group:
\/ - a / char
\d{1,3} - 1 to 3 digits
$ - end of string.
Visual graph (generated here):
This should work. You were matching an optional slash and then an optional digit from 1 to 3; this matches an optional combination of a slash and 1-3 of any digits. Also, your original regex could match 0 digits at the beginning; I believe that this was in error, so I fixed that.
var regex = /^(\d{1,3}[A-Z]{0,1}(\/\d{1,3})?)?$/g;
console.log("77A/7 - "+!!("77A/7").match(regex));
console.log("77/ - "+!!("77/").match(regex));
console.log("35 - "+!!("35").match(regex));
console.log("35A - "+!!("35A").match(regex));
console.log("35A/44 - "+!!("35A/44").match(regex));
console.log("35/44 - "+!!("35/44").match(regex));
console.log("34/ - "+!!("34/").match(regex));
console.log("A/3 - "+!!("A/3").match(regex));
console.log("[No string] - "+!!("").match(regex));

Regex validation for mixed digits for a max of 6 characters

I need a regex validation for mixed length, a total length of 6 characters in that 4-6 characters in caps/numbers and 0-2 spaces.
I tried like
^[A-Z0-9]{4,6}+[\s]{0,2}$
but it results in a max length of 8 characters, but I need a max of 6 characters.
If the alphanumeric chars should only appear at the start of the string and the whitespaces can appear at the end (i.e. the order of the alphanumerics and whitespaces matters), you may use
/^(?=.{6}$)[A-Z0-9]{4,6}\s*$/
See the regex demo
Details
^ - start of string
(?=.{6}$) - the string length is restricted to exactly 6 non-line break chars
[A-Z0-9]{4,6} - 4, 5 or 6 uppercase ASCII letters or digits
\s* - 0+ whitespaces (but actually, only 0, 1 or 2 will be possible to add as the total length is already validated with the lookahead)
$ - end of string.
If you want to match the alphanumeric and whitespaces anywhere inside the string, you need a lookaround based regex like
^(?=(?:[^A-Z0-9]*[A-Z0-9]){4,6}[^A-Z0-9]*$)(?=(?:\S*\s){0,2}\S*$)[A-Z0-9\s]{6}$
See the regex demo
Details
^ - start of string
(?=(?:[^A-Z0-9]*[A-Z0-9]){4,6}[^A-Z0-9]*$) - a positive lookahead that requires the presence of 4 to 6 letters or digits anywhere inside the string
(?=(?:\S*\s){0,2}\S*$) - a positive lookahead that requires the presence of 0 to 2 whitespaces anywhere inside the string
[A-Z0-9\s]{6} - 6 ASCII uppercase letters, digits or whitespaces
$ - end of string.
To shorten the pattern, the second lookahead can be written as (?!(?:\S*\s){3}), it will fail the match if there are 3 whitespace chars anywhere inside the string. See the regex demo.
You can use | characters to accommodate several cases into one.
const regex = /(^[A-Z0-9]{4}\s{2}$)|(^[A-Z0-9]{5}\s$)|(^[A-Z0-9]{6}$)/g;
alert(regex.test(prompt('Enter input, including space(s)')));
If you want to match zero, one or two spaces at the end, you could use an alternation for those 3 cases.
^(?:[A-Z0-9]{4}[ ]{2}|[A-Z0-9]{5}[ ]|[A-Z0-9]{6})$
Regex demo
Explanation
^ Assert the start of the string
(?: Non capturing group
[A-Z0-9]{4}[ ]{2} Match uppercase or digit 4 times followed by 2 spaces
| Or
[A-Z0-9]{5} Match uppercase or digit 5 times followed by 1 space
| Or
[A-Z0-9]{6} Match uppercase or digit 6 times
) Close non capturing group
$ Assert the end of the string

Regular Expression - Avoid a string in expression

I am trying to create a regex that should match following cases.
if exact match of words 'first, second, third' then match should fail - but if there are any characters around it, then the string should be matched.
Also I need to avoid certain set of characters in the string. [()!=<>", ] - if these characters are part of string then match result should fail.
I looked at few examples & negative look ahead but did not get the right regex yet.
^(?!first$|second$|third$|fou rth$)[^()!=<>", ]+
desired output:
first - fail
second - fail
1first - pass
first1 - pass
1first1 - pass
fou rth - fail - it has space in between word and is from ignore list
newTest - pass
new(test - fail - since ( is not allowed character
space word - fail - since space is non allowed character
The regex needs to support case insensitive words
Any help appreciated. I am using javascript.
Try this Regex:
^(?!.*[()!=<>", ])(?!(?:first|second|third)$).+$
Click for Demo
Explanation:
^ - asserts the start of the string
(?!.*[()!=<>", ]) - negative lookahead to validate that the test string does not contain any of these characters - (, ), !, =, <, >, ,,
(?!(?:first|second|third)$) - At this moment we are at the beginning of the test string. This position should not be immediately followed by (first or second or third) and then by the end of the string($)
.+ - matches 1+ occurrences of any character but not a newline character
$ - asserts the end of the string

Regular Expression to also allow slash "/" with existing Regex

I am facing difficulty to allow slash "/" with an existing regex
Below is an existing Regex which allows dot and numbers:
val.match(/^[0-9]+(\.[0-9]{1,2})?$/)
I changes it to...
val.match(/^[0-9]+([./][0-9\/]{1,2})?$/)
But this one won't allow the number like 1.5/384 where both dot/period and slash simultaneously.
Can someone help me with it?
You may add an optional non-capturing group after your main pattern part to match 1 or 0 occurrences of / followed with 1 or more digits:
/^\d+(?:\.\d{1,2})?(?:\/\d+)?$/
^^^^^^^^^^
See the regex demo
Details
^ - start of string
\d+ - 1 or more digits
(?:\.\d{1,2})? - an optional sequence of . and then 1 or 2 digits
(?:\/\d+)? - an optional sequence of / and then 1+ digits
$ - end of string.
If the number after / can be float in the same format as the first number:
/^\d+(?:\.\d{1,2})?(?:\/\d+(?:\.\d{1,2})?)?$/
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
This should do what you want :
^(\d+(?:\.\d{1,2})?\/?(?:\d+\.\d{1,2})?)$
See this Regex101.com
Edit : Corrected the fact that it didn't match 1 or 1.5

Update regex pattern to allow .xx instead of just 0.xx

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

Categories