EDIT: I recently found out(with help from some kind Stack Overflow users) that there are valid YouTube videos that are only letters.
Same question as here but with the addition of checking letters into the equation.
I was wondering if it is possible for the video ids for YouTube videos to be comprised of just numbers like this:
12345678901.
I'm writing an expression to validate a string that is a YouTube video id. Here is a simplified version of the expression in action(source here for further debugging):
const foo = /((http?(?:s)?:?\/\/)?(www\.)?)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?&v=))((?:\w|-){11})((?:\&|\?)\S*)?|(?:^(\w|-){11}$)|(?:\w|-){11}$/;
let bar = "dQw4w9WgXcQ"
// logs true
console.log("is valid: " + foo.test(bar));
Is it possible to write a regular expression that matches a string that does not only contain numbers or letters?
These should work:
But these shouldn't:
Used a negative lookahead to check if its not all numbers, then followed by a check if its all word characters and a dash only pattern.
/^(?!\d+$)[\w\-]+$/
let valids = [
'abcdefghijk',
'ecK3EnyGD8o',
'1s3get2-3ds',
'4bc2qfs2wrf',
'28yq389gfwg',
'3oyh8pw489p'
];
let invalids = [
'12345678910',
'18974107892351240891751928347819234',
'Stack Overflow',
'kjsad;kflj;klasdfkjalk;sdfjlkas',
'!&$@#)&&()%&*(#@$&('
];
let pattern = /^(?!\d+$)[\w\-]+$/;
for (var i = 0; i < valids.length; i++)
console.log(valids[i], pattern.test(valids[i]))
for (var i = 0; i < invalids.length; i++)
console.log(invalids[i], pattern.test(invalids[i]))
Use
^[\d_-]*[a-zA-Z][-\w]*$
See regex proof.
EXPLANATION
| Part of Expression | What it Does |
|---|---|
^ |
the beginning of the string |
[\d_-]* |
any character of: digits (0-9), _, - (0 or more times(matching the most amount possible)) |
[a-zA-Z] |
any character of: a-z, A-Z |
[-\w]* |
any character of: - word characters (a-z, A-Z, 0-9, _) (0 or more times (matching the most amount possible)) |
$ |
before an optional \n, and the end of the string |
JavaScript code:
const oks = [
'abcdefghijk',
'ecK3EnyGD8o',
'1s3get2-3ds',
'4bc2qfs2wrf',
'28yq389gfwg',
'3oyh8pw489p'
];
const nonoks = [
'12345678910',
'18974107892351240891751928347819234',
'Stack Overflow',
'kjsad;kflj;klasdfkjalk;sdfjlkas',
'!&$@#)&&()%&*(#@$&('
];
const regex = /^[\d_-]*[a-zA-Z][-\w]*$/;
for (const i of oks)
console.log(i, regex.test(i))
for (const i of nonoks)
console.log(i, regex.test(i))
Try this on for size:
const re = /[\w]*(\p{L}\d|\d\p{L})[\w]*/u;
console.log("abcdefghijk".match( re ) || "Failed");
console.log("ecK3EnyGD8o".match( re ) || "Failed");
console.log("1s3get2-3ds".match( re ) || "Failed");
console.log("4bc2qfs2wrf".match( re ) || "Failed");
console.log("28yq389gfwg".match( re ) || "Failed");
console.log("3oyh8pw489p".match( re ) || "Failed");
console.log("12345678910".match( re ) || "Failed");
console.log("18974107892351240891751928347819234".match( re ) || "Failed");
console.log("Stack Overflow".match( re ) || "Failed");
console.log("kjsad;kflj;klasdfkjalk;sdfjlkas".match( re ) || "Failed");
console.log("!&$@#)&&()%&*(#@$&(".match( re ) || "Failed");
You meant for "abcdefghijk" to be a fail case right? It only contains letters.
"1s3get2-3ds" will fail as it contains a hyphen. If you want to consider valid symbols just add them to the "[\w]", like so for hyphen: [-\w]