Find longest word in Javascript array - javascript

So I'm working on this codility coding challenge and I cannot get the code to work for all inputs, particularly large ones. The rules for this are here.
To summarize, I need each word in the string to be tested for: alpha-numeric characters only, even number of letters, and odd number of digits.
For the sample input - "test 5 a0A pass007 ?xy1", this solution effectively ignores "test" (it has an even number of digits, 0 digits) and "?xy1" (special character, ?). From the leftover options, it chooses pass007 as the longest word and returns 7 (length of word).
I start by splitting the string into separate words and then generating if statements to check if each word in my new array meets the requirements, isAlpha, isAlphaEven (remainder 0 for even # of letters), isNumeric (remainder 1 for odd numbers).
Any idea what I am doing wrong? Thanks much! :)
// you can write to stdout for debugging purposes,
// e.g. console.log('this is a debug message');
function solution(S) {
// write your code in JavaScript (Node.js 8.9.4)
// you can write to stdout for debugging purposes,
// e.g. console.log('this is a debug message');
// write your code in JavaScript (Node.js 8.9.4)
var words = S.split(" ");
var isAlpha = /^[0-9a-zA-z]*$/;
var isAlphaEven = /^[a-zA-Z]/;
var isNumeric = /^[0-9]/;
var maxLength = -1;
for(var i = 0; i <= words.length - 1; i++) {
if(words[i].match(isAlpha)
&& words[i].replace(isAlphaEven, '').length % 2 == 0
&& words[i].replace(isNumeric, '').length % 2 == 1
|| words[i].match(isNumeric)
) {
maxLength = Math.max(maxLength, words[i].length);
//console.log(words[i], maxLength);
}
}
return maxLength;
}

One problem is that the patterns
var isAlphaEven = /^[a-zA-Z]/;
var isNumeric = /^[0-9]/;
can only match characters at the start of the string: ^ anchors to the beginning. It also isn't a global match, so it'll only replace one character. Another problem is that you're replacing the matches with the empty string, rather than testing the number of matches. To test the number of matches, use .match instead, with the global flag, and check the length of the resulting array (or null if there are no matches):
function solution(S) {
// write your code in JavaScript (Node.js 8.9.4)
// you can write to stdout for debugging purposes,
// e.g. console.log('this is a debug message');
// write your code in JavaScript (Node.js 8.9.4)
var words = S.split(" ");
var allAlphaNumeric = /^[\da-z]*$/i;
var alpha = /[a-z]/gi;
var numeric = /\d/g;
var maxLength = -1;
for (var i = 0; i <= words.length - 1; i++) {
if (words[i].match(allAlphaNumeric) &&
(words[i].match(alpha) || []).length % 2 == 0 &&
(words[i].match(numeric) || []).length % 2 == 1
) {
maxLength = Math.max(maxLength, words[i].length);
}
}
return maxLength;
}
console.log(solution("test 5 a0A pass007 ?xy1"));
Note that you can use the case-insensitive flag instead of repeating a-zA-Z, and you can use \d instead of [0-9] if you wish.
While you could use .replace to figure out the number of matches, it'd be convoluted: you'd have to replace everything that doesn't match with the empty string, which would make the code's intent somewhat confusing.

You already have the answer why your approach didn't work as expected.
So I thought I could add a slightly different approach with multiple .filter() steps
function findLongestWord(input) {
const isAlphaNumericOnly = /^[a-z0-9]+$/i;
const numbersOnly = /\d/g;
const alphaOnly = /[a-z]/gi;
const validWords = input.split(/\s/)
.filter(word => isAlphaNumericOnly.test(word))
.filter(word => (word.match(numbersOnly) || []).length % 2 === 1)
.filter(word => (word.match(alphaOnly) || []).length % 2 === 0)
.sort((a, b) => b.length - a.length);
return {
word: validWords[0],
length: validWords[0] ? validWords[0].length : -1
};
}
console.log(findLongestWord("test 5 a0A pass007 ?xy1"));

Related

Having trouble re-indexing my array after looping from the end of the array while adding characters in place

I am trying to solve this particular algorithm question:
You are given a license key represented as a string S which consists only alphanumeric character and dashes. The string is separated into N+1 groups by N dashes.
Given a number K, we would want to reformat the strings such that each group contains exactly K characters, except for the first group which could be shorter than K, but still must contain at least one character. Furthermore, there must be a dash inserted between two groups and all lowercase letters should be converted to uppercase.
Given a non-empty string S and a number K, format the string according to the rules described above.
Example 1:
Input: S = "5F3Z-2e-9-w", K = 4
Output: "5F3Z-2E9W"
Explanation: The string S has been split into two parts, each part has 4 characters.
Note that the two extra dashes are not needed and can be removed.
Example 2:
Input: S = "2-5g-3-J", K = 2
Output: "2-5G-3J"
Explanation: The string S has been split into three parts, each part has 2 characters except the first part as it could be shorter as mentioned above.
Note:
The length of string S will not exceed 12,000, and K is a positive integer.
String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-).
String S is non-empty.
I have written the following code:
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 1
i-- //re-index bc adding to the array
}
pos++
}
return s
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
I am pretty sure the flaw in my logic is due to the re-index, but I can't figure out how to address it.
You should not alter the index. Using splice to insert an element pushes the other elements back, however since you iterate from back to front that doesn't matter. You've already handled the shifted elements.
Another issue is setting pos = 1 in the loop. This is directly followed by pos++. So when pos reaches K the value of pos will be reset to 2 at the end of the loop. Either set pos = 0 (in the loop) so it ends on 1 or move pos++ into the else section.
const licenseKeyFormatting = (S, K) => {
//convert to array, remove special characters, and capitalize
let s = [...S.replace(/\W/g, '').toUpperCase()]
let pos = 1
//from end of array add '-' for every K
for (let i = s.length - 1; i > 0; i--) {
if (pos === K) {
s.splice(i, 0, '-')
pos = 0
}
pos++
}
return s.join("") // <- added join for cleaner console output
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) //5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) //2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // this test case fails should be A-A-A-A, I am getting AAA-A
my way....
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()]
, p = 0
;
for (let i=arr.length;i--;)
{
p = ++p % K // p = (p+1) % K
if (!p&&i) arr.splice(i,0,'-') // if p===0 and i>0
}
return arr.join('')
}
console.log(licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log(licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log(licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A
OR: (more simple)
function licenseKeyFormatting( S, K )
{
let arr = [...S.replace(/\W/g, '').toUpperCase()];
for (let p=arr.length-K;p>0;p-=K) arr.splice(p,0,'-');
return arr.join('');
}
console.log( licenseKeyFormatting("5F3Z-2e-9-w", 4)) // 5F3Z-2E9W
console.log( licenseKeyFormatting("2-5g-3-J", 2)) // 2-5G-3J
console.log( licenseKeyFormatting("a-a-a-a-", 1)) // A-A-A-A

Removing last vowels from every word in a sentence javascript

Write a function that removes the last vowel in each word in a sentence.
Examples:
removeLastVowel("Those who dare to fail miserably can achieve greatly.")
➞ "Thos wh dar t fal miserbly cn achiev gretly."
removeLastVowel("Love is a serious mental disease.")
➞ "Lov s serios mentl diseas"
removeLastVowel("Get busy living or get busy dying.")
➞ "Gt bsy livng r gt bsy dyng"
What I am doing is
function sumDigProd(arr) {
let ans = arr.split(" ");
let array = [];
for (i = 0; i < ans.length; i++) {
for (j = 0; j < ans[i].length; j++) {
var vowelAtLast;
if (
ans[i][j].toLowerCase() == "a" ||
ans[i][j].toLowerCase() == "e" ||
ans[i][j].toLowerCase() == "i" ||
ans[i][j].toLowerCase() == "o" ||
ans[i][j].toLowerCase() == "u"
) {
vowelAtLast = ans[i][j];
}
}
var idex = ans[i].lastIndexOf(vowelAtLast);
console.log(idex,ans[i],ans[i][idex]);
ans[i].replace(ans[i][idex],'')
array.push(ans[i])
console.log(ans)
}
console.log(ans)
return array.join(" ");
}
console.log(sumDigProd("youuo goalo people."));
Here, console.log(idex,ans[i],ans[i][idex]); gives me the correct output for example:
4 "youuo" "o"
But now when I try to do:
ans[i].replace(ans[i][idex],'')
console.log(ans)
I get
["youuo", "goalo", "people."]
again instead i should get
["youu", "goalo", "people."]
after the first time loop runs... and then at last I get the output as
["youu", "goal", "peopl."]
as per the problem but I get
["youuo", "goalo", "people."]
why are no changes made by the replace method here?
A problem is that
ans[i].replace(ans[i][idex], '')
will only replace the first occurrence of whatever character ans[i][idex] is. Eg
aza
would result in
za
Another issue is that you must use the return value of .replace, else it'll go unused and be irrelevant; you'd want something like
ans[i] = ans[i].replace(ans[i][idex], '')
instead, so that the item at that index in the array is properly reassigned.
But it would probably be easier to use a regular expression: match a vowel, followed by capturing zero or more non-vowels in a capture group, with lookahead matching a space or the end of the string. Then replace with the first capture group, thereby removing the last vowel:
const sumDigProd = str => str.replace(
/[aeiou]([^aeiou]*?)(?= |$)/gi,
'$1'
);
console.log(sumDigProd("youuo goalo people."));
[aeiou]([^aeiou]*?)(?= |$) means:
[aeiou] - Any vowel
([^aeiou]*?) - Match and capture:
[^aeiou]*? Any non-vowel, lazily (capture group), up until
(?= |$) - lookahead matches a space or the end of the string
Then
'$1' - Replace with the capture group
To change your original code, identify the last index of a vowel by iterating from the final index of the string and going backwards. When one is found, reassign the string at ans[i] and .sliceing the portions behind and in front of the found vowel:
function sumDigProd(arr) {
let ans = arr.split(" ");
for (i = 0; i < ans.length; i++) {
for (j = ans[i].length - 1; j >= 0; j--) {
if (
ans[i][j].toLowerCase() == "a" ||
ans[i][j].toLowerCase() == "e" ||
ans[i][j].toLowerCase() == "i" ||
ans[i][j].toLowerCase() == "o" ||
ans[i][j].toLowerCase() == "u"
) {
ans[i] = ans[i].slice(0, j) + ans[i].slice(j + 1);
// go to next word
break;
}
}
}
return ans.join(' ');
}
console.log(sumDigProd("youuo goalo people."));

Get current sentence by cursor/caret position

I have a string containing multiple sentences. I also have the current cursor/caret position.
I need to be able to extract the current sentence at the given cursor position.
For example, take this string:
This is the first sentence. And this is the second! Finally, this is the third sentence
If the current cursor position is 33 then the cursor is in the second sentence.
In which case, the result returned should be:
And this is the second!
I only need to use the standard sentence definers of .?!
Any help with this would be greatly appreciated.
Although I am expecting regex to be required, if there is a faster alternative using native methods I would be interested in that also.
Here is a way to achieve what you need: use String#split with /[?!.]/g to get an array of sentences and then iterate over the array to sum up the lengths of the sentences found, and if the index is smaller than the count, return the sentence.
function getSentenceByPos(idx, str) {
pos = 0;
array = str.split(/[?!.]/g);
for (var i=0; i<array.length; i++) {
pos += array[i].length + 1;
if (pos >= idx) {
return array[i];
}
}
}// 26 still 1 then `.`. 51 then `!` - 53 is 3rd sentence!
document.write(getSentenceByPos(53, "This is the first sentence. And this is the second! Finally, this is the third sentence"));
I wanted to add an answer that doesn't use regular expression to split up the
string because doing so is quite inefficient and would likely be very slow on
larger chunks of text.
The most efficient way to do it would probably be to use a couple of loops to search, requiring only 2 passes to find the ends of the sentence.
var sentenceFromPos = function (s, pos) {
var len = s.length,
start,
end,
char;
start = pos;
end = pos;
while (start >= 0) {
char = s.charAt(start);
if (char === '.' || char === '?' || char === '!') {
break;
}
start -= 1;
}
while (end < len) {
char = s.charAt(end);
if (char === '.' || char === '?' || char === '!') {
break;
}
end += 1;
}
return s.substring(start + 1, end + 1).trim();
};
var phrase = 'This is the first sentence. And this is the second! Finally, this is the third sentence';
console.log(sentenceFromPos(phrase, 10));
console.log(sentenceFromPos(phrase, 33));
console.log(sentenceFromPos(phrase, 53));
This function will respect cursors over the limits of the phrases (like ! or .)
function getPhrase(string, cursor) {
phrases = string.match(/.*?(!|\.|$)/g)
basecursor = 0;
phrase = phrases[0]
for(ii=0; ii<phrases.length-1; ii++) {
if (basecursor+phrases[ii].length<cursor) {
phrase = phrases[ii+1]
basecursor += phrases[ii].length
}
}
return(phrase)
}
string = "This is the first sentence. And this is the second! Finally, this is the third sentence"
cursor = 0
phrase = getPhrase(string, cursor)
document.write(phrase)

Finding a pattern in a binary string

I'm trying to find a repeating pattern in a string of binary digits.
eg. 0010010010 or 1110111011 = ok
not. 0100101101 = bad
The strings are 10 digits long (as above) & i guess 2 iterations of the 'pattern' are the minimum.
I started manually setting a 'bank' of patterns that the program could match it with but there must be a better way using an algorithm?
Searching got me nowhere - i think the language & terminology i'm using is incorrect..
Quite a challenge. What about this function?
function findPattern(n) {
var maxlen = parseInt(n.length/2);
NEXT:
for(var i=1; i<=maxlen; ++i) {
var len=0, k=0, prev="", sub;
do {
sub = n.substring(k,k+i);
k+= i;
len = sub.length;
if(len!=i) break;
if(prev.length && sub.length==i && prev!=sub) continue NEXT;
if(!prev.length) prev = sub;
} while(sub.length);
var trail = n.substr(n.length-len);
if(!len || len && trail==n.substr(0,len)) return n.substr(0,i);
}
return false;
}
It even works for any length strings with any contents. See the fiddle
Inspired by Jack's and Zim-Zam's answer, here is the list for brute force algorithm:
var oksubs =
["001","010","011","100","101","110",
"0001","0010","0011","0100","0101","0110","0111",
"1000","1001","1010","1011","1100","1101","1110",
"00000","00001","00011","00101","00110","00111","01000",
"01001","01010","01011","01100","01101","01110","01111",
"10000","10001","10011","10101","10110","10111","11000","11001",
"11010","11011","11100","11101","11110","11111"];
Thanks to Jack's comment, here is both short and effective code:
function findPattern(n) {
var oksubs = [n.substr(0,5),n.substr(0,4),n.substr(0,3)];
for(var i=0; i<oksubs.length; ++i) {
var sub = oksubs[i];
if((sub+sub+sub+sub).substr(0,10)==n) return sub;
}
return false;
}
You've only got 2^10 patterns, that's a small enough number that you can just precompute all of the valid strings and store the results in a 1024-element boolean array; if a string is valid, then convert it to an integer (e.g. "0000001111" = 15) and store "true" in the resulting array index. To check if a string is valid, convert it to an integer and look up the index in the precomputed boolean array.
If your strings are longer than 10 digits then you'll need to be more clever about determining if a string is valid, but since you only have 1024 strings you might as well be lazy about this.
maintaining an array of 2^10 wont help becuase it wont indicate which strings have repeating patterns.
To have a repeating pattern the pattern length can be only be <= 5
there can be a pattern of length 1.but pattern of length five will cover it. [STEP EDITED]
if there a pattern with length 2, there is always a pattern ith length 4.
from (1),(2), (3) and (4) , it is only necessary to check patterns of length 3,4 and 5
that means if first three digits match with next three digits proceed till end of string else break and go to 7
else match first four digits with next four if match proceed till end of string
else break and go to 8
else match first five digits with next four if match proceed till end of string
else break and go to 9
if one of 6, 7,8 is false, return failure
My brute-force approach would be:
by example
givenString: 0010010010:
create list of possible patterns for givenString 0010010010:
possiblePatterns = [00, 010, 0010, 00100, 01, 001, 0100, 10, 100]
repeat them to make strings with length >= 10
testPattern0 = 0000000000 // 00 00 00 00 00
testPattern1 = 010010010010 // 010 010 010 010
testPattern2 = 001000100010 // 0010 0010 0010
...
and check...
for each testPattern:
if '0010010010' is a substring of testPattern ==> pattern found
one of the matching strings:
testPattern2: 010010010010
givenString : 0010010010
found patterns:
foundPatterns = [010, 001, 100]
As one can see, this is a possibly redundant list as all patterns are basically the same, just shifted. But depending on the use case, this may actually be what you want.
Code:
function findPatterns(str){
var len = str.length;
var possible_patterns = {}; // save as keys to prevent duplicates
var testPattern;
var foundPatterns = [];
// 1) create collection of possible patterns where:
// 1 < possiblePattern.length <= str.length/2
for(var i = 0; i <= len/2; i++){
for(var j = i+2; j <= len/2; j++){
possible_patterns[str.substring(i, j)] = 0;
}
}
// 2) create testPattern to test against given str where:
// testPattern.length >= str.length
for(var pattern in possible_patterns){
testPattern = new Array(Math.ceil(len/pattern.length)+1).join(pattern);
if(testPattern.indexOf(str) >= 0){
foundPatterns.push(pattern);
}
}
return foundPatterns;
}
==> fiddle
As far as I can tell, there are 62 patterned binary strings of length 10 => 2^1 + 2^2 + 2^3 + 2^4 + 2^5. Here's some code that lists them and matches a patterned string:
function binComb (n){
var answer = []
for (var i=0; i<Math.pow(2,n);i++){
var str = i.toString(2)
for (var j=str.length; j<n; j++){
str = "0" + str
}
answer.push(str)
}
return answer
}
function allCycles(){
var answer = {}, cycled = ""
for (var i=1; i<=5; i++){
var arr = binComb(i)
for (var j=0; j<arr.length; j++){
while(cycled.length < 10){
cycled += arr[j]
if (10 - cycled.length < arr[j].length)
cycled += arr[j].substr(0,10 - cycled.length)
}
if (answer[cycled])
answer[cycled].push(arr[j])
else answer[cycled] = [arr[j]]
cycled = ""
}
}
return answer
}
function getPattern (str){
var patterns = allCycles()
if (patterns[str])
return patterns[str]
else return "Pattern not found."
}
OUTPUT:
console.log(getPattern("0010010010"))
console.log(getPattern("1110111011"))
console.log(getPattern("0100101101"))
console.log(getPattern("1111111111"))
["001"]
["1110"]
Pattern not found.
["1", "11", "111", "1111", "11111"]
In Python (again) but without regexps:
def is_repeated(text):
'check if the first part of the string is repeated throughout the string'
len_text = len(text)
for rep_len in range(len_text // 2, 0, -1):
reps = (len_text + rep_len) // rep_len
if (text[:rep_len] * reps).startswith(text):
return rep_len # equivalent to boolean True as will not be zero
return 0 # equivalent to boolean False
matchstr = """\
1001110011
1110111011
0010010010
1010101010
1111111111
0100101101
"""
for line in matchstr.split():
print('%r has a repetition length of %i' % (line, is_repeated(line)))
Output:
'1001110011' has a repetition length of 5
'1110111011' has a repetition length of 4
'0010010010' has a repetition length of 3
'1010101010' has a repetition length of 4
'1111111111' has a repetition length of 5
'0100101101' has a repetition length of 0
This answer uses a Python regular expression to be compiled with the VERBOSE flag set which allows multi-line regexps with comments and non-significant spaces. I also use named groups in the regexp.
The regexp was developed with the aid of the Kodos tool.
The regexp searches for the longest repeating strings of length five then four then three repeating characters. (two repeating characters is redundant as it is equal to the longer four; and similarly one repeating is made redundant by five).
import re
rawstr = r"""
(?P<r5> .{5}) (?P=r5) |
(?P<r4>(?P<_42> .{2}) .{2}) (?P=r4) (?P=_42) |
(?P<r3>(?P<_31> .{1}) .{2}) (?P=r3){2} (?P=_31)
"""
matchstr = """\
1001110011
1110111011
0010010010
1010101010
1111111111
0100101101
"""
for matchobj in re.finditer(rawstr, matchstr, re.VERBOSE):
grp, rep = [(g, r) for g, r in matchobj.groupdict().items()
if g[0] != '_' and r is not None][0]
print('%r is a repetition of %r' % (matchobj.group().strip(), rep))
Gives the output:
'1001110011' is a repetition of '10011'
'1110111011' is a repetition of '1110'
'0010010010' is a repetition of '001'
'1010101010' is a repetition of '1010'
'1111111111' is a repetition of '11111'

Javascript regular expressions problem

I am creating a small Yahtzee game and i have run into some regex problems. I need to verify certain criteria to see if they are met. The fields one to six is very straight forward the problem comes after that. Like trying to create a regex that matches the ladder. The Straight should contain one of the following characters 1-5. It must contain one of each to pass but i can't figure out how to check for it. I was thinking /1{1}2{1}3{1}4{1}5{1}/g; but that only matches if they come in order. How can i check if they don't come in the correct order?
If I understood you right, you want to check if a string contains the numbers from 1 to 5 in random order. If that is correct, then you can use:
var s = '25143';
var valid = s.match(/^[1-5]{5}$/);
for (var i=1; i<=5; i++) {
if (!s.match(i.toString())) valid = false;
}
Or:
var s = '25143';
var valid = s.split('').sort().join('').match(/^12345$/);
Although this definitely can be solved with regular expressions, I find it quite interesting and educative to provide a "pure" solution, based on simple arithmetic. It goes like this:
function yahtzee(comb) {
if(comb.length != 5) return null;
var map = [0, 0, 0, 0, 0, 0];
for(var i = 0; i < comb.length; i++) {
var digit = comb.charCodeAt(i) - 48;
if(digit < 1 || digit > 6) return null;
map[digit - 1]++;
}
var sum = 0, p = 0, seq = 0;
for(var i = 0; i < map.length; i++) {
if(map[i] == 2) sum += 20;
if(map[i] >= 3) sum += map[i];
p = map[i] ? p + 1 : 0;
if(p > seq) seq = p;
}
if(sum == 5) return "Yahtzee";
if(sum == 23) return "Full House";
if(sum == 3) return "Three-Of-A-Kind";
if(sum == 4) return "Four-Of-A-Kind";
if(seq == 5) return "Large Straight";
if(seq == 4) return "Small Straight";
return "Chance";
}
for reference, Yahtzee rules
For simplicity and easiness, I'd go with indexOf.
string.indexOf(searchstring, start)
Loop 1 to 5 like Max but just check indexOf i, break out for any false.
This also will help for the small straight, which is only 4 out of 5 in order(12345 or 23456).
Edit: Woops. 1234, 2345, 3456. Sorry.
You could even have a generic function to check for straights of an arbitrary length, passing in the maximum loop index as well as the string to check.
"12543".split('').sort().join('') == '12345'
With regex:
return /^([1-5])(?!\1)([1-5])(?!\1|\2)([1-5])(?!\1|\2|\3)([1-5])(?!\1|\2|\3|\4)[1-5]$/.test("15243");
(Not that it's recommended...)
A regexp is likely not the best solution for this problem, but for fun:
/^(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5).{5}$/.test("12354")
That matches every string that contains exactly five characters, being the numbers 1-5, with one of each.
(?=.*1) is a positive lookahead, essentially saying "to the very right of here, there should be whatever or nothing followed by 1".
Lookaheads don't "consume" any part of the regexp, so each number check starts off the beginning of the string.
Then there's .{5} to actually consume the five characters, to make sure there's the right number of them.

Categories

Resources