Allowing the RegEx to start with a period or minus sign - javascript

I've spent hours tring to find a solution. I have the following RegEx:
(?=.)^(([1-9][0-9]{0,8})|([0-9]))?(\.[0-9]{1,2})?$
I want to add the ability for the first character to match a minus sign but still match the rest of the stated RegEx.
I need these to work:
.0
.34
-.34
-30.0
-33.03
-34
-2
I need these to fail:
-04.4
043
3.
-
$34.33
1234567890.23
(any non-numeric character)
Thank you for your assistance.

You can use this regex:
^-?(?:[1-9][0-9]{0,8}(?:\.[0-9]{1,2})?|\.[0-9]{1,2})$
RegEx Demo
EDIT: If you want to allow 0.45 as valid input then use:
^-?(?:[1-9][0-9]{0,8}(?:\.[0-9]{1,2})?|0*\.[0-9]{1,2})$

Adding the optional -? at the correct place should do the trick.
Also I'm fairly sure you don't need all these capturing groups (see demo here):
^-?(?=.)(?:[1-9][0-9]{0,8}|0)?(?:\.[0-9]{1,2})?$
^-? # optional leading -
(?=.) # followed by at least one character
(?: # non capturing group
[1-9][0-9]{0,8} # number without leading 0
| # or
0 # single 0
)? # integer part is optional
(?:\.[0-9]{1,2})?$ # decimal part

This should work for you
^(?:-[1-9.]{1}[0-9]*|\.|0\.)\.?[0-9]{0,2}$
Demo

Related

What will be the RegEx one or more, Which can validate all WebSocket Urls ? is there any npm module for the same? [duplicate]

I'm trying to write a regex for valid websocket address but I couldn't figure out what's wrong. Here's what I've already tried
/(^ws:\/\/|^wss:\/\/)(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\:)|([a-zA-Z]+))([0-9]{1,5})/gm
Regex should match below
ws://0.0.0.0:8080
wss://192.168.0.25:12345
ws://localhost:3333
You may use
/^(wss?:\/\/)([0-9]{1,3}(?:\.[0-9]{1,3}){3}|[a-zA-Z]+):([0-9]{1,5})$/
See the regex demo
Note that [a-zA-Z]+ won't be enough as it only matches ASCII letters.
Use [^\/]+ instead if you want to match any chars but /:
/^(wss?:\/\/)([0-9]{1,3}(?:\.[0-9]{1,3}){3}|[^\/]+):([0-9]{1,5})$/
See this regex demo.
To just match FQDNs, use
/^(wss?:\/\/)([0-9]{1,3}(?:\.[0-9]{1,3}){3}|(?=[^\/]{1,254}:[0-9]{1,5}$)(?:(?=[a-zA-Z0-9-]{1,63}\.)(?:xn--+)?[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,63}):([0-9]{1,5})$/
Adaped from this solution by Tim Pietzcker. There are all the explanations in his post. See this regex demo.
The main problem was with :: it was only matched after numeric IP pattern, not after the [a-zA-Z]+.
Details
^ - start of string
(wss?:\/\/) - ws:// or wss://
([0-9]{1,3}(?:\.[0-9]{1,3}){3}|[a-zA-Z]+) - 1 to 3 digits followed with 3 occurrences of . and 1 to 3 digits or 1+ letters (or, if [^\/]+ is used, 1+ chars other than /)
: - :
([0-9]{1,5}) - 1 to 5 digits
$ - end of string.
The second alternation does not match the :
You could move it outside of the alternation to match it for both of the options.
If you don't need the capturing groups, you could omit them.
The first alternation could be shortened making the extra s optional:
^(wss?:\/\/)(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})|([a-zA-Z]+)):[0-9]{1,5}$
Regex demo

How to modify this hashtag regex to check if the second character is a-z or A-Z?

I'm building on a regular expression I found that works well for my use case. The purpose is to check for what I consider valid hashtags (I know there's a ton of hashtag regex posts on SO but this question is specific).
Here's the regex I'm using
/(^|\B)#(?![0-9_]+\b)([a-zA-Z0-9_]{1,20})(\b|\r)/g
The only problem I'm having is I can't figure out how to check if the second character is a-z (the first character would be the hashtag). I only want the first character after the hashtag to be a-z or A-Z. No numbers or non-alphanumeric.
Any help much appreciated, I'm very novice when it comes to regular expressions.
As I mentioned in the comments, you can replace [a-zA-Z0-9_]{1,20} with [a-zA-Z][a-zA-Z0-9_]{0,19} so that the first character is guaranteed to be a letter and then followed by 0 to 19 word characters (alphanumeric or underscore).
However, there are other unnecessary parts in your pattern. It appears that all you need is something like this:
/(?:^|\B)#[a-zA-Z][a-zA-Z0-9_]{0,19}\b/g
Demo.
Breakdown of (?:^|\B):
(?: # Start of a non-capturing group (don't use a capturing group unless needed).
^ # Beginning of the string/line.
| # Alternation (OR).
\B # The opposite of `\b`. In other words, it makes sure that
# the `#` is not preceded by a word character.
) # End of the non-capturing group.
Note: You may also replace [a-zA-Z0-9_] with \w.
References:
Word Boundaries.
Difference between \b and \B in regex.
The below should work.
(^|\B)#(?![0-9_]+\b)([a-zA-Z][a-zA-Z0-9_]{0,19})(\b|\r)
If you only want to accept two or more letter hashtags then change {0,19} with {1,19}.
You can test it here
In your pattern you use (?![0-9_]+\b) which asserts that what is directly on the right is not a digit or an underscore and can match a lot of other characters as well besides an upper or lower case a-z.
If you want you can use this part [a-zA-Z0-9_]{1,20} but then you have to use a positive lookahead instead (?=[a-zA-Z]) to assert what is directly to the right is an upper or lower case a-z.
(?:^|\B)#(?=[a-zA-Z])[a-zA-Z0-9_]{1,20}\b
Regex demo

regex to only allow an input to 3 decimal places with 0.001 being the smallest number possible, not 0

I am trying to write a regex to allow a user enter a positive number and to 3 decimal places. My regex looks like this, however, it isn't working as I would like.
/\d*[1-9](\.\d{0,3})?/
This allows the user to enter 1.000 as the smallest number, however, it doesn't allow a user to enter 0.001 which should be the smallest number possible to enter into the input.
Does anyone know what the regex should be to solve this?
Your code has another issue where it can not match 10 since you are not allowing the ones place to be 0.
You need to use some or statements
const re = /(^([1-9]|\d{2,})(\.\d{0,3})?|0\.\d{0,2}[1-9])$/
const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1"]
tests.forEach(n => console.log(n, re.test(n)))
const re = /^(?!0+(?:\.0+)?$)\d+(?:\.\d+)?$/
const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1","1.22","1.222"]
tests.forEach(n => console.log(n, re.test(n)))
Explanation:
^ # beginning of string
(?! # negative lookahead, make sure we haven't after:
0+ # 1 or more zero
(?: # start non capture group
\. # a dot
0+ # 1 or more zero
)? # end group, optional
$ # end of string
) # end lookahead
\d+ # 1 or more digits
(?: # start non capture group
\. # a dot
\d+ # 1 or more digits
)? # end group, optionnal
$ # end of string
Personally I would just check for 0 and make the regex a lot simpler, but here is a solution, where the required decimal places can be adjusted by changing {1,3}.
The jist of this regex is that we allow any number greater than two digits , then allow only 1-9 for one digit, then optionally require up to 1 decimal with 1-3 digits afterwards.
const r = /^((([0-9]{2,}){1}|[1-9]{1})(\.[0-9]{1,3}){0,1})$/;
const tests = ['1','2','0','1.001','1.001.1','999.001','9.01','9.0100','abc'];
tests.forEach(t=>console.log(t,r.test(t)));
Another option is to use a negative lookahead to assert from the start of the string what is on the right is neither a dot or zero repeated until the end of the string:
^(?![0.]+$)\d+(?:\.\d{1,3})?$
See a Regex demo
Explanation
^ Start of the string
(?![0.]+$) Negative lookahead to assert what is on the right is not what is listed in the character class repeated 1+ times until the end of the string
\d+ Match 1+ times a digit
(?:\.\d{1,3})? Optional non capturing group which matches a dot and 1+ times a digit
$ End of the string
const tests = ["0.001", "0.1", "0","0.0", "0.000","10.001", "10","11","1","1.22","1.222"]
tests.forEach(n => console.log(parseFloat(n) >= 0.001))
I really think this is being overthought.
The answer is here.
([1-9]\.[0-9][0-9][0-9]|[0]\.[1-9][0-9][0-9]|[0]\.[0][1-9][0-9]|[0]\.[0][0][1-9])
This should match 0.001~9.999

Regex that allows a single whitespace in the middle but with character limit.

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!)

regex pattern to match a type of strings

I need to match the below type of strings using a regex pattern in javascript.
E.g. /this/<one or more than one word with hyphen>/<one or more than one word with hyphen>/<one or more than one word with hyphen>/<one or more than one word with hyphen>
So this single pattern should match both these strings:
1. /this/is/single-word
2. /this/is-more-than/single/word-patterns/to-match
Only the slash (/) and the 'this' string in the beginning are consistent and contains only alphabets.
You can use:
\/this\/[a-zA-Z ]+\/[a-zA-Z ]+\/[a-zA-Z ]+
Working Demo
I think you want something like this maybe?
(\/this\/(\w+\s?){1,}\/\w+\/(\w+\s?)+)
break down:
\/ # divder
this # keyword
\/ # divider
( # begin section
\w+ # single valid word character
\s? # possibly followed by a space
) # end section
{1,} # match previous section at least 1 times, more if possible.
\/ # divider
\w+ # single valid word character
\/ # divider
( # begin section
\w+ # single valid word character
\s? # possible space
) # end section
Working example
This might be obvious, however to match each pattern as a separate result, I believe you want to place parenthesis around the whole expression, like so:
(\/[a-zA-Z ]+\/[a-zA-Z ]+\/[a-zA-Z ]+\/[a-zA-Z ]+)
This makes sure that TWO results are returned, not just one big group.
Also, your question did not state that "this" would be static, as the other answers assumed... it says only the slashes are static. This should work for any text combo (no word this required).
Edit - actually looking back at your attempt, I see you used /this/ in your expression, so I assume that's why others did as well.
Demo: http://rubular.com/r/HGYp2qtmAM
Modified question samples:
/this/is/single-word
/this/is-more-than/single/word-patterns/to-match
Modified again The sections may have hyphen (no spaces) and there may be 3 or 4 sections beyond '/this/'
Modified pattern /^\/this(?:\/[a-zA-Z]+(?:-[a-zA-Z]+)*){3,4}$/
^
/this
(?:
/ [a-zA-Z]+
(?: - [a-zA-Z]+ )*
){3,4}
$

Categories