Regex exact match on number, not digit - javascript

I have a scenario where I need to find and replace a number in a large string using javascript. Let's say I have the number 2 and I want to replace it with 3 - it sounds pretty straight forward until I get occurrences like 22, 32, etc.
The string may look like this:
"note[2] 2 2_ someothertext_2 note[32] 2finally_2222 but how about mymomsays2."
I want turn turn it into this:
"note[3] 3 3_ someothertext_3 note[32] 3finally_2222 but how about mymomsays3."
Obviously this means .replace('2','3') is out of the picture so I went to regex. I find it easy to get an exact match when I am dealing with string start to end ie: /^2$/g. But that is not what I have. I tried grouping, digit only, wildcards, etc and I can't get this to match correctly.
Any help on how to exactly match a number (where 0 <= number <= 500 is possible, but no constraints needed in regex for range) would be greatly appreciated.

The task is to find (and replace) "single" digit 2, not embedded in
a number composed of multiple digits.
In regex terms, this can be expressed as:
Match digit 2.
Previous char (if any) can not be a digit.
Next char (if any) can not be a digit.
The regex for the first condition is straightforward - just 2.
In other flavours of regex, e.g. PCRE, to forbid the previous
char you could use negative lookbehind, but unfortunately Javascript
regex does not support it.
So, to circumvent this, we must:
Put a capturing group matching either start of text or something
other than a digit: (^|\D).
Then put regex matching just 2: 2.
The last condition, fortunately, can be expressed as negative lookahead,
because even Javascript regex support it: (?!\d).
So the whole regex is:
(^|\D)2(?!\d)
Having found such a match, you have to replace it with the content
of the first capturing group and 3 (the replacement digit).

You can use negative look-ahead:
(\D|^)2(?!\d)
Replace with: ${1}3
If look behind is supported:
(?<!\d)2(?!\d)
Replace with: 3

See regex in use here
(\D|\b)2(?!\d)
(\D|\b) Capture either a non-digit character or a position that matches a word boundary
(?!\d) Negative lookahead ensuring what follows is not a digit
Alternations:
(^|\D)2(?!\d) # Thanks to #Wiktor in the comments below
(?<!\d)2(?!\d) # At the time of writing works in Chrome 62+
const regex = /(\D|\b)2(?!\d)/g
const str = `note[2] 2 2_ someothertext_2 note[32] 2finally_2222 but how about mymomsays2.`
const subst = "$13"
console.log(str.replace(regex, subst))

Related

How can I write the Javascript Regular Expression pattern to handle these conditions

In My exercise, I'm given a task to write a regular expression pattern that validates username input for storage into database.
Usernames can only use alpha-numeric characters.
The only numbers in the username have to be at the end. There can be zero or more of them at the end. Username cannot start with the number.
Username letters can be lowercase and uppercase.
Usernames have to be at least two characters long. A two-character username can only use alphabet letters as characters.
I succeeded to pass all tests except one
A1 is not supposed to match the patern
let userCheck = /^[A-Za-z]+\w\d*$/;
let result = userCheck.test(username);
You can use an alternation after ^[a-z] the first letter to require either [a-z]+ one or more letters followed by \d* any amount of digits | OR \d{2,} two or more digits up to $ end of the string.
let userCheck = /^[a-z](?:[a-z]+\d*|\d{2,})$/i;
See this demo at regex101 - Used with the i-flag (ignore case) to shorten [A-Za-z] to [a-z].
PS: Just updated my answer at some late cup of coffee ☕🌙. Had previously misread the question and removed my answer in meanwhile. I would also have missed the part with e.g. Z97 which I just read at the other answers comments. It's much more of a challenge than at first glance... obviously :)
Edit:
My first answer did not fully solve the task. This regex does:
^([A-Za-z]{2}|[A-Za-z]\w{2,})$
it matches either two characters, or one character followed by at least two characters and/or digits (\w == [A-Za-z0-9]). See the demo here: https://regex101.com/r/sh6UpX/1
First answer (incorrect)
This works for your description:
let userCheck = /^[A-Za-z]{2,}\d*$/;
let result = userCheck.test(username);
Let me explain what went wrong in your regex:
/^[A-Za-z]+\w\d*$/
You correctly match, that the first character is only a letter. The '+' however only ensures, that it is matched at least one time. If you want to match something an exact number of times, you can append '{x}' to your match-case. If you rather want to match a minimum and maximum amount of times, you can append '{min, max}'. In your case, you only have a lower limit (2 times), so the max stays empty and means unlimited times: {2,}
After your [2 - unlimited] letters, you want to have [0 - unlimited] numbers. '\w' also matches letters, so we can just remove it. The end of your regex was correct, as '\d' matches any digit, and '*' quantifies the previous match for the range [0 - unlimited].
I recommend using regex101.com for testing and developing regex patterns. You can test your strings and get very good documentation and explanation about all the tags. I added my regex with some example strings to this link:
https://regex101.com/r/qPmwhG/1
The strings that match will be highlighted, the others stay without highlighting.

Javascript regex to make sure that string matches format x:y

I am trying to parse a string which has two numbers, both can be between 1 and 3 digits, and will have a colon in between. Here are some examples:
"1:1"
"1:12"
"12:1"
"123:12"
Also, the given string may also be invalid, and I need to detect if it is. My attempts so far to make sure the string is valid have looked like this: .match(/[1-9]\:[1-9]/);. But then I noticed that this wont work if a string such as this is inputted: "characters12:4characters". How would I go about validating the string to make sure it is in the format x:y?
Any help would be deeply appreciated.
Edit: numbers which contain 0 at the beginning is valid, but may not be given.
You may use
/^\d{1,3}:\d{1,3}$/
See the regex demo
Details
^ - start of a string
\d{1,3} - one, two or three digits (\d is a shorthand character class that matches any digit (it can also be written as a [0-9] character class) and {1,3} is a limited quantifier that matches1 to 3 consecutive occurrences of the quantified subpattern)
: - a colon
\d{1,3} - one, two or three digits
$ - end of the string.

Regexp: numbers and few special characters

I am buried in a RegExp hell and can't find way out, please help me.
I need RegExp that matches only numbers (at least 1 number) and one of this characters: <, >, = (exactly one of them one time).
My reg. expression looks like this:
^[0-9]+$|^[=<>]{1}$
And I thought it should match when my string containts one or more digits and exactly 1 special character defined by me. But it doesn't act correctly. I think there might be problem with my start/end of string definition but Im not sure about that.
Examples that should pass include:
<1
=2
22>
>1
=00123456789
Examples that should not pass this reg. exp.:
<<2
==222
<>=2
I thought it should match when my string containts one or more digits and exactly 1 special character
No, the original pattern matches a string contains one or more digits or exactly 1 special character. For example it will match 123 and = but not 123=.
Try this pattern:
^\d+[=<>]$
This will match that consists of one or more digits, followed by exactly one special character. For example, this will match 123= but not 123 or =.
If you want your special character to appear before the number, use a pattern like this instead:
^[=<>]\d+$
This will match =123 but not 123 or =.
Update
Given the examples you provided, it looks like you want to match any string which contains one or more digits and exactly one special character either at the beginning or the end. In that case use this pattern:
^([=<>]\d+|\d+[=<>])$
This will match <1, =2, 22>, and >1, but not 123 or =.
Just use [0-9]+[=<>]
Here are visualizers of your regexp and this one:
http://www.regexper.com/#%5E%5B0-9%5D%2B%24%7C%5E%5B%3D%3C%3E%5D%7B1%7D%24
http://www.regexper.com/#%5B0-9%5D%2B%5B%3D%3C%3E%5D
Your regex says:
1 or more numbers OR 1 symbol
Also, the ^ and $ means the whole string, not contains. if you want a contains, drop them. I don't know if you have a space between the number and symbol, so put in a conditional space:
[0-9]+\s?[=<>]{1}
This should work.
^[0-9]+[=<>]$
1 or more digits followed by "=<>".
Try this regex:
^\d+[=<>]$
Description
This one:
/^\d+[<>=]$|^[<>=]\d+$/

Javascript - Matching a hyphen in regex

I'm trying to match a string using regex (of which I am new to) but I can't get it to match.
These should be accepted:
GT-00-TRE
KK-10-HUH
JU-05-OPR
These should not:
HTH-00-AS
HM-99-ASD
NM-05-AK
So the pattern goes 2 letters, hyphen, 2 digits (between 00 and 11 inclusive), hyphen, 3 letters.
So far the best I can come up with is:
var thePattern = /^[a-z]{2}[-][00-11][-][a-z]{3}$/gi;
I can't help but feel that I'm pretty close.
Can anyone give me any pointers?
Thanks.
This should be what you need:
var thePattern = /^[a-z]{2}[-](0\d|1[0-1])[-][a-z]{3}$/gi;
In order to do a range 00-11, you have to say "(0 followed by 0-9) or (1 followed by 0 or 1)". This is because specifying a range within [] only works for single digits. Luckily your case is pretty simple, otherwise it could get quite complex to work around that.
Your regex is OK, but for one thing: the digits matching is a bit more complex
(0\d|10|11)
you want to match a zero followed by a digit (\d) OR (|) a ten OR a eleven.
Something in square brackets represents just a single character in a range. [0-5] means any single digit between 0 and 5, [a-q] means any lowercase letter from a to q. There's no such thing as [00-11] because it would require to work on more than one character at a time.

invalid quantifier javascript error on regex

What am I doing wrong here?
I'm trying to replace a number in a string with another number using javascript. I have a long string that has the number 1 in it several times. I need to replace the number 1 with 2 in every case except where 1 has another number on either side. I did a bunch of google searches for how to use regex (I'm totally new to regex) and I came up with this.
string.replace(/(?<!\d)1(?!\d)/,2);
Basically, I want the regex to match (and thus replace) every occurrence of the number 1 where it is surrounded by anything except another number. I don't want the match to include the surrounding characters--only the number 1.
I keep getting the invalid quantifier error in my firebug console. What am I doing wrong?
It's this bit: (?<!\d). There's no (?<, only (?:, (?=, and (?!.
JavaScript doesn't have look-behind, but I think you can work around it in this case, like this:
str = str.replace(/(^|\D)1(?!\d)/g, "$12")
That captures the character immediately prior to the digit, then echoes it back ($1 in the replacement string) followed by the new content (2). The ^ near the beginning allows for the digit being the first character in the string.
Live example
Breaking it down:
(^|\D) Match either start-of-string, or a non-digit, and capture the result
1 Match the digit 1...
(?!\d) ...but only if it isn't followed by a digit
And in the replacement, $12 is not "replace with capture group 12" (which is what it looks like to me), but "replace with capture group 1 followed by the digit 2."

Categories

Resources