Regex Js must have 1 alphabet and 1 character - javascript

the following is my regex
regex: /^[a-zA-Z]+-.*(?=.*\d)(?=.*[a-zA-Z]).*-[0-9]+-[a-zA-Z]+-[0-9]+$/
the overall rules is: alphabet-alphanumeric-number-alphabet-number
im having problem at .*(?=.*\d)(?=.*[a-zA-Z]).*
the expected output for it to get a successful result for the alphanumeric part is
abc123
123abc
1abc23
ab23ca
and fail if
abcde
12345
but the result i get is all successful include the expected fail result
abc-abc-123-abc-123
abc-123-123-abc-123
i see that using lookahead will also get the input after the dash(-) of the alphanumeric that caused it to be successful although it is not the expected result

You could try
^[a-zA-Z]+-(?![a-zA-Z]+-|\d+-)[a-zA-Z0-9]+-\d+-[a-zA-Z]+-\d+$
It uses this negative lookahead to check the second subsequence is not only made by alphabets or numerics
(?![a-zA-Z]+-|\d+-)
Alternatively, you can use this positive lookahead to check the second subsequence is made by a digit preceded any alphabets or the other way around
(?=[a-zA-Z]+\d|\d+[a-zA-Z])
It is important to use a lookahead to check it right at the start of the subsequence, and do not use .* in this situation since it might consume a - and checks the wrong sequence behind it.
You may check the test result here

For the alphanumeric part, you can assert not only digits till the next hyphen.
Using a case insensitive match:
^[a-z]+-(?!\d+-)[a-z]*\d[a-z\d]*-\d+-[a-z]+-\d+$
^ Start of string
[a-z]+- Match 1+ chars a-z and -
(?!\d+-) Negative lookahead, assert not only digits followed by -
[a-z]*\d[a-z\d]*- Match optional chars a-z, match a digit and optional chars a-z or a digit
\d+-[a-z]+-\d+ Match digits - chars a-z - digits
$ End of string
Regex demo
const regex = /^[a-z]+-(?!\d+-)[a-z]*\d[a-z\d]*-\d+-[a-z]+-\d+$/i;
[
"abc-abc-123-abc-123",
"abc-123-123-abc-123",
"abc-abcde-123-abc-123",
"abc-12345-123-abc-123",
"abc-ab23ca-123-abc-123",
"abc-1abc23-123-abc-123"
].forEach(s =>
console.log(`${s} --> ${regex.test(s)}`)
);

why not:
/([A-Za-z]+[0-9]+|[0-9]+[A-Za-z]+)/
-- or --
/[A-Za-z]/.test(val) && /[0-9]/.test(val)
var cases = [
"abc123",
"123abc",
"1abc23",
"ab23ca",
// fail
"abcde",
"12345",
"abc-abc-123-abc-123", // not clear if these should fail?
"abc-123-123-abc-123"
];
cases.forEach(val => {
var ok = /([A-Za-z]+[0-9]+|[0-9]+[A-Za-z]+)/.test(val)
//var ok = /[A-Za-z]/.test(val) && /[0-9]/.test(val);
console.log(val, ok);
});

Related

Regex to capture all numbers in a string that ends with a number

I'm trying to write a regex that captures all the numbers in a string BUT only if the string ends with numbers.
I worked out the pattern would require a repeating capture group:
^(\D*(\d+))+$
So
the string starts
there are 0 or more non-digit characters
then 1 or more digits (which we capture)
that pattern repeats until the end of the string
My problem is that it seems that in repeated capture groups you only get the last match returned to you. (demo)
Can anyone show me where I'm going wrong?
You may use this regex with a lookahead:
\d+(?=(?:\w+\d)?\b)
RegEx Demo
RegEx Breakdown:
\d+: Match 1+ digits
(?=: Start Lookahead assertion
(?:\w+\d)?: Optionally match 1 or more word characters followed by a digit
\b: Word boundary
): End Lookahead assertion

Regex for only letters and numbers but no numbers at the beginning or end

I want to make a regex that matches only letters and numbers, but no numbers at the beginning or the end:
ahmed0saber is valid
0ahmedsaber is not valid
ahmedsaber0 is not valid
ahmed_saber is not valid
I tried this
[a-z0-9_]
but it doesn't work as expected!
This should work ^[a-z][a-z\d]*[a-z]$
const regex = /^[a-z][a-z\d]*[a-z]$/
const tests = ['ahmed0saber', '0ahmedsaber', 'ahmedsaber0', 'ahmed_saber']
tests.forEach(test)
function test(name) {
console.log(name, name.match(regex) ? 'yes' : 'no')
}
If you also want to allow a single character:
^[a-z](?![a-z\d]*\d$)[a-z\d]*$
Explanation
^ Start of string
[a-z] Match a single char a-z
(?![a-z\d]*\d$) Negative lookahead, assert the the string does not end on a digit
[a-z\d]* Match optional chars a-z or digits
$ End of string
See a regex demo.
Or if a lookbehind assertion is supported:
^[a-z][a-z\d]*$(?<!\d)
Explanation
^ Start of string
[a-z] Match a single char a-z
[a-z\d]* Match optional chars a-z or digits
$ End of string
(?<!\d) Negative lookabehind, assert not a digit at the end
See another regex demo.

React.js RegExp always returns false

I have this code to check if my fields are all good to go. I have my back-end up and working, but I'm struggling to check the regex inside my react method. All I did was created a regex in regex101 before used it on the input pattern, but I wanted to change it to the method. So basically the regex always returns false...
// Then check regex
const regInput = new RegExp(
'^(?:(?:IT|SM)d{2}[A-Z]d{22}|CYd{2}[A-Z]d{23}|NLd{2}[A-Z]{4}d{10}|LVd{2}[A-Z]{4}d{13}|(?:BG|BH|GB|IE)d{2}[A-Z]{4}d{14}|GId{2}[A-Z]{4}d{15}|ROd{2}[A-Z]{4}d{16}|KWd{2}[A-Z]{4}d{22}|MTd{2}[A-Z]{4}d{23}|NOd{13}|(?:DK|FI|GL|FO)d{16}|MKd{17}|(?:AT|EE|KZ|LU|XK)d{18}|(?:BA|HR|LI|CH|CR)d{19}|(?:GE|DE|LT|ME|RS)d{18}|ILd{21}|(?:AD|CZ|ES|MD|SA)d{22}|PTd{23}|(?:BE|IS)d{24}|(?:FR|MR|MC)d{25}|(?:AL|DO|LB|PL)d{26}|(?:AZ|HU)d{27}|(?:GR|MU)d{28})$'
);
if (!regInput.test(this.state.iban)) {
this.setState({
error: true,
errorMsg:
'Sąskaitsssos numeris įvestas klaidingai, bandykite dar kartą',
});
console.log('error');
return;
} else {
console.log('LT597300010145601329');
}
Seems like your regex is the problem. If you are going to have the pattern 2 letters followed by 18 digits, you can try this regex:
^[\w]{2}[\d]{18}$
Here is the regex for an input like: LT597300010145601329
Try:
[a-zA-Z]{2}\d{18}
Note: If you want only uppercase letters, then: [A-Z]{2}\d{18}
According to this link here,
An IBAN, or international bank account number starts with a two-digit country code, then two numbers, followed by several more alphanumeric characters.
You can use the following regex:
^[a-zA-Z]{2}[\d]{2}[a-zA-Z0-9]{14,20}$
In short, this accepts a value with 2 letters(irrespective of the case) followed by 2 digits followed by alphanumeric characters ranging from 14-20 characters (You can change the length constraint if you have more details on the pattern).
Detailed explaination:
Match a single character present in the list below [a-zA-Z]
{2} matches the previous token exactly 2 times
a-z matches a single character in the range between a (index 97) and z (index 122) (case sensitive)
A-Z matches a single character in the range between A (index 65) and
Z (index 90) (case sensitive)
Match a single character present in the list below [\d]
{2} matches the previous token exactly 2 times
\d matches a digit (equivalent to [0-9])
Match a single character present in the list below [a-zA-Z0-9]
{14,20} matches the previous token between 14 and 20 times, as many
times as possible, giving back as needed (greedy)
$ asserts position at the end of a line

positive lookahead

Use lookaheads to match a string that is greater than 5 characters long and have two consecutive digits.
I know the solution should be
/(?=\w{6,})(?=\D*\d{2})/
But why the second element is
(?=\D*\d{2})
Instead of
(?=\d{2})
Please help me to understand this.
Actually, /(?=\w{6,})(?=\D*\d{2})/ does not ensure there will be a match in a string with 2 consecutive digits.
Check this demo:
var reg = /(?=\w{6,})(?=\D*\d{2})/;
console.log(reg.test("Matches are found 12."))
console.log(reg.test("Matches are not found 1 here 12."))
This happens because \D* only matches any non-digit chars, and once the \w{6,} matches, (?=\D*\d{2}) wants to find the two digits after any 0+ digits, but it is not the case in the string.
So, (?=\w{6,})(?=\D*\d{2}) matches a location in the string that is immediately followed with 6 or more word chars and any 0+ non-digit chars followed with 2 digits.
The correct regex to validate if a string contains 6 or more word chars and two consecutive digits anywhere in the string is
var reg = /^(?=.*\w{6,})(?=.*\d{2})/;
Or, to support multiline strings:
var reg = /^(?=[^]*\w{6,})(?=[^]*\d{2})/;
where [^] matches any char. Also, [^] can be replaced with [\s\S] / [\d\D] or [\w\W].
And to match a string that is greater than 5 characters long and have two consecutive digits you may use
var reg = /^(?=.*\d{2}).{5,}$/
var reg = /^(?=[\s\S]*\d{2})[\s\S]{5,}$/
where
^ - start of string
(?=[\s\S]*\d{2}) - there must be two digits anywhere after 0+ chars to the right of the current location
[\s\S]{5,} - five or more chars
$ - end of string.
The lookahead has to allow the 2 digits anywhere in the input. If you used just (?=\d{2}) then the 2 digits would have to be at the beginning.
You could also use (?=.*\d{2}). The point is that \d{2} has to be preceded by something that can match the rest of the input before the digits.

Validating userName using Regex

The only numbers in the username have to be at the end. There can be zero or more of them at the end.
Username letters can be lowercase and uppercase.
Usernames have to be at least two characters long. A two-letter username can only use alphabet letter characters.
I'm trying with this but I'm stalled. /\d+$\w+/gi
/^[a-z]{2,}\d*$/i is:
^ : the begining
[a-z] : a character (a to z), you can add as many allowed characters as you want
{2,} : at least 2 of them
\d* : 0 or more digits
$ : the end
i : ignore case sensetivity (both lowercases and uppercases are allowed)
Username having characters and digit and min 2 character long
/^[a-zA-Z]{2,}\d*$/i
Test result :
UserNam9 = pass
9username = fail
Userna99 = pass
usernameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee = pass
Us = pass
U = fail
/^[A-z]{2,}[A-z0-9]{0,}$/
/^ // start of line
[A-z]{2,} //alphabet characters 2 or more
[A-z0-9]{0,} //numbers and alphabet
$/ // end of line
You've missed cases when there's a letter in the start, followed by 2 or more numbers.
U99 = fail
d345 = fail
My solution passes these tests, as well:
/^[a-z]{2,}\d*$|(?=\w{3,})^[a-z]{1,}\d+$/i
Using positive lookahead I am making sure that in the second case there are at least 3 alphanumeric characters.
Simplified version of /^[a-z]{2,}\d*$|(?=\w{3,})^[a-z]{1,}\d+$/i:
/^\D(\d{2,}|\D+)\d*$/i
Code explanation:
^ - start of input
\D - first character is a letter
\d{2,} - ends with two or more numbers
| - or
\D+ - has one or more letters next
\d* - and ends with zero or more numbers
$ - end of input
i - ignore case of input
This is my answer, it passed all the tests:
/^[a-z][a-z]+\d*$|^[a-z]\d{2,}$/i
First Part: 2 letters (or more) and zero or more numbers
Or
Second Part: 1 letter and 2 or more numbers

Categories

Resources