Here's the pattern I'm working on:
var re = /(\d{1,2}\.(?=\d{1,2}))/;
What I would like for this to return is a one or two digit number (which will never be greater than 24, since it is for a time mgmt app), which may or may not be followed by a decimal point with either one or two trailing digits, but not more than two.
I'm not sure about the parenthetical substring match mixed with the lookahead. I just guessed and nested them. Ultimately, if my syntax is okay, I think the only thing I am missing is how to suggest that the pattern may or may not have leading digits, and may or may not contain a decimal with trialing digits.
Let me know if you need more info.
Update, Examples:
We are only dealing with time, and no more time than can occur in a single day. 24 would be the highest input.
Valid:
23.75
1.4
1
0.5
0
.2
Invalid:
1.897
%#$##$#
Words
other characters
Newest Update:
Since this is a decimal, 23.75 works. We are not counting minutes, but rather fractions of hours.
Also, for the record, I tried validating using methods and conditionals, and it was letting letters pass through after the decimals. I have made the decision to go with regex.
If "any number given will be less than 24", so that doesn't need to be separately tested for, then the following expression will work.
^\d{0,2}(\.\d{0,2}){0,1}$
See http://rubular.com/r/YDfHr5T5sQ
Tested against:
23.75 pass
1.4 pass
1 pass
0.5 pass
0 pass
.2 pass
1.897 fail
%#$##$# fail
Words fail
other characters fail
Explanation:
^ start matching at the start of the string
\d{0,2} look for zero to two digits
( ){0,1}$ look for this next thing zero or one time, then the end of the string
\.\d{0,2} match exactly one decimal followed by up to two digits
Note - this regex does match the "empty string". You might want to test for that separately if there's a chance that will somehow make its way to this expression...
Simple code to test in your javascript:
var str = "12.345";
var m = str.match(/^\d{0,2}(?:\.\d{0,2}){0,1}$/);
var goodTime;
if (!m) {
alert(str + " is not a good time");
}
else {
goodTime = m[0];
alert("found a good time: " + goodTime);
}
Note - I made a tweak to the regex - adding ?: in the "bit after the decimal" group. This just means "match but don't capture" so the result will return only the match m[0] and not the group .34 in m[1]. It doesn't actually matter since I assign goodTime the value in m[0] (but only if it's a good time). You can see this in action here
Well you can try this regex
^(?![3-9]\d|[2][5-9]|24[.])\d{1,2}([.]\d{1,2})?$
But you don't need to use regex here,just parse the string to number and check if it's less than or equal to 24
What about this one:
([1]?[0-9])|((20)|(21)|(22)|(23)|(24)){0,1}([.][0-9]{0,2})?
Edit: I would advise you to do only simple checks in RegEx and test semantic correctness (eg. less than 24) somewhere else as it gets really complicated. Time would also not allow 23:74 but 23:59...
Related
I am trying to solve 'JavaScript Algorithms and Data Structures Projects: Telephone Number Validator' #freeCodeCamp.
I need to test if string contains 10 digits and what I've come up with returns false and I don't understand why.
console.log(/\d{10}/g.test("555-555-5555"))
If you want to do this with a single regular expression, you can use:
console.log(/^(?:\D*\d){10}\D*$/g.test("555-555-5555"))
console.log(/^(?:\D*\d){10}\D*$/g.test("555-555-55555"))
requiring the input to be composed of exactly 10 digits in addition to any number of other non-digit characters - but replacing non-digits with the empty string first would be a more intuitive and readable solution.
Here \d{10} means ten consecutive digits, not "ten digits with whatever in the middle, that's cool".
If want just 10 digits, you may want to strip non-digit data first:
let number = "555-555-5555";
// Remove all non-digit values (\D) which leaves only digits
let digits = number.replace(/\D/g, '').length;
It seems that your idea is correct, but this specific challenge has so many options for dashes [-] and parentheses [()] as inputs that there is a more efficient way to pass this.
function telephoneCheck(str) {
let phoneRegex = /^(1\s?)?(\d{3}|\(\d{3}\))[\s\-]?\d{3}[\s\-]?\d{4}$/
return phoneRegex.test(str);
}
The above is a way to complete the challenge in a single line of Regex, which can save you (or anyone else reading this in the future) a lot of time and space! Cheers
I have the following specifications for a regex:
-> The string starts with a string of three numbers
-> It is followed by a '-'
-> That is followed by three uppercase vowels
-> That is followed by a '-'
-> That is followed by three numbers
-> That is followed by a final '-'
-> That is followed by the last three uppercase vowels.
-> Second set of numbers can not equal the first.
-> The second group of letters can not equal the first.
-> The groups of numbers may not contain zero.
A passable string is:
368-IOU-789-AIO.
An invalid string is:
368-AEO-368-AEI
354-AOU-431-AOU
Currently, I have something like this:
([0-9]+[0-9]+[0-9]+[/AEIOU/]+[0-9]+[0-9]+[0-9])
What you have won't work since + means "one or more of". For example, the sequence [0-9]+[0-9]+[0-9]+ will match anywhere between three and an infinite number of digits.
In addition, your current attempt:
allows for one to an infinite number of vowels (and possibly / character);
doesn't require a vowel set at the end;
doesn't require the - separators; and
may allow for arbitrary content before and after the match.
You should be able to use the {count} specifier to get an exact quantity. All but one of those limitations can be done with any basic regex engine, with something like:
^[1-9]{3}-[AEIOU]{3}-[1-9]{3}-[AEIOU]{3}$
The ^ and $ anchors means start and end of string, [1-9]{3} gives you exactly three non-zero digits, [AEIOU]{3} gives you exactly three vowels, and - gives you the literal separator character.
The "groups cannot be identical" rule is a little more problematic. I would just post process for that to ensure it's not violated. The following pseudo-code is what I mean:
def isValid(str):
if not str.regex_match("^[1-9]{3}-[AEIOU]{3}-[1-9]{3}-[AEIOU]{3}$"):
return false
return str[0..2] != str[8..10]
and str[4..6] != str[12..14]
The alternative will be a rather complex regex that future developers will probably curse you for inflicting on them :-)
Note that your "The groups of numbers may not contain zero" is a little ambiguous in that it may mean no zeros are allowed or just 000 is not allowed. I've assumed the former but it's easy adjustable to cater for the latter:
def isValid(str):
if not str.regex_match("^[0-9]{3}-[AEIOU]{3}-[0-9]{3}-[AEIOU]{3}$"):
return false
return str[0..2] != str[8..10]
and str[4..6] != str[12..14]
and str[0..2] != "000"
and str[8..10] != "000"
You can use capture group and backreferences
^([0-9]{3})-([AEIOU]{3})-(?:(?!\1)[0-9]){3}-(?:(?!\2)[AEIOU]){3}$
Regex Demo
The groups of numbers may not contain zero. From this if you meant only digits between 1 to 9 then you can replace [0-9] with [1-9]
If you don't want to have 000 then you can add a negative lookahead ^(?!.*000) to avoid matching 000
Max Length of string is 5 (including one alphabet). If there is no alphabet, allowed length of digits is 4.
Digits allowed: 0 to 9999
One alphabet is allowed(Only if string has at least one number). Some examples:
Allowed: 1a, a2, 1111a, 1a22, 9999
Not allowed: 99999, 11111,a,aa
I tried:
^(?:[0-9]|[a-z](?=[^a-z]*$)){1,5}$
This works for cases: 1a, a2, 1111a, 1a22, 9999. But it incorrectly allows 99999 as well.
Any help on how to restrict the digit length?
^(?:(?=\d*[a-z]\d*$)(?=.*[0-9])(?:[a-z0-9]){1,5}|[0-9]{1,4})$
Try this.See demo.
https://regex101.com/r/fX3oF6/10
Regexes aren't good at keeping counts of things, as you've discovered. In this case, a lookahead will put you right:
^\d{1,4}$|^(?=\d*[a-z]\d*$)[a-z\d]{1,5}$
We start by using ^\d{1,4}$ to get the simplest case out of the way first. If that fails, the second alternative, the second alternative takes over. The first thing it does is use (?=\d*[a-z]\d*$) to assert that there is exactly one letter in the string. If the lookahead succeeds, the match position returns to the beginning of the string, allowing us match the whole string again, this time with [a-z\d]{1,5}$.
It isn't really necessary to verify that the rest of the characters are digits at this point. I could have used (?=[^a-z]*[a-z][a-z]*$ instead. We just need to make sure it looks at the whole string. I just think it's more self-documenting with \d*.
Note that this regex will match a string consisting of just a letter. If you want to make sure there's at least one digit as well, change the final {1,5} to {2,5}.
Here's the demo.
Use {size} for restrict the length of String in regex.
I update the regex:
^(?:(?=.*[a-z])(?:[0-9]|[a-z]){1,5}|[0-9]{4})$
It's been a while that I am juggling around this. Hope you can give me
some pointers.
All I want to achieve is, the string should contain EXACTLY 4 '-' and 10 digits in any giver order.
I created this regex : ^(-\d-){10}$
It does enforce max-length of 10 on digits but I am not getting a way to implement max-length of 4 for '-'
Thanks
Ok, here's a pattern:
^(?=(?:\d*?-){4}\d*$)(?=(?:-*?\d){10}-*$).{14}$
Demo
Explanation:
The main part is ^.{14}$ which simply checks there are 14 characters in the string.
Then, there are two lookaheads at the start:
(?=(?:\d*?-){4}\d*$)
(?=(?:-*?\d){10}-*$)
The first one checks the hyphens, and the second one checks the digits and make sure the count is correct. Both match the entire input string and are very similar so let's just take a look at the first one.
(?:\d*?-){4} matches any number of digits (or none) followed by a hyphen, four times. After this match, we know there are four hyphens. (I used an ungreedy quantifier (*?) just to prevent useless backtracking, as an optimization)
\d*$ just makes sure the rest of the string is only made of digits.
I'm trying to create a regular expression in javascript for a UK bank sort code so that the user can input 6 digits, or 6 digits with a hyphen between pairs. For example "123456" or "12-34-56". Also not all of the digits can be 0.
So far I've got /(?!0{2}(-?0{2}){2})(\d{2}(-\d{2}){2})|(\d{6})/ and this jsFiddle to test.
This is my first regular expression so I'm not sure I'm doing it right. The test for 6 0-digits should fail and I thought the -? optional hyphen in the lookahead would cause it to treat it the same as 6 0-digits with hyphens, but it isn't.
I'd appreciate some help and any criticism if I'm doing it completely incorrectly!
Just to answer your question, you can validate user input with:
/^(?!(?:0{6}|00-00-00))(?:\d{6}|\d\d-\d\d-\d\d)$/.test(inputString)
It will strictly match only input in the form XX-XX-XX or XXXXXX where X are digits, and will exclude 00-00-00, 000000 along with any other cases (e.g. XX-XXXX or XXXX-XX).
However, in my opinion, as stated in other comments, I think it is still better if you force user to either always enter the hyphen, or none at all. Being extra strict when dealing with anything related to money saves (unknown) troubles later.
Since any of the digits can be zero, but not all at once, you should treat the one case where they are all zero as a single, special case.
You are checking for two digits (\d{2}), then an optional hyphen (-?), then another two digits (\d{2}) and another optional hyphen (-?), before another two digits (\d{2}).
Putting this together gives \d{2}-?\d{2}-?\d{2}, but you can simplify this further:
(\d{2}-?){2}\d{2}
You then use the following pseudocode to match the format but not 000000 or 00-00-00:
if (string.match("/(\d{2}-?){2}\d{2}/") && !string.match("/(00-?){2}00/"))
//then it's a valid code, you could also use (0{2}-?){2}0{2} to check zeros
You may wish to add the string anchors ^ (start) and $ (end) to check the entire string.