5

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.

4
  • 1
    Can you give a couple of examples of the output you want to get for a particular input? And are you sure the separator is always a . and never say :? If the input is 123.456 what would you like to happen? Commented Jun 25, 2013 at 14:01
  • I updated the entry with examples. Commented Jun 25, 2013 at 14:07
  • 1
    why use regex for this Commented Jun 25, 2013 at 14:21
  • What do you want to do with 12.345? Is it valid, invalid, do you truncate it to 12.34 or round it to 12.35? How can you be sure that the number will not be greater than 24, yet it might be a string? What do you want to do about 12.89PM? How about 12,45 (which is how Europeans would write 12.45) Commented Jun 25, 2013 at 14:32

3 Answers 3

14

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

Sign up to request clarification or add additional context in comments.

8 Comments

I will check for empty, null, undefined, etc, elsewhere. Once the string is validated and typed as a double, there are other checks I have to do. I have to play around with this, but I think this will work. ty
You don't try to replace - just match: var str = "12.34"; var m = str.match(/^\d{0,2}(\.\d{0,2}){0,1}$/); . m[0] will contain the match - if one exists. Otherwise it will be empty.
I have updated my answer with a "tell you like you don't know anything" bit at the end... Don't worry we have all been there. Let me know if it's now clear and solved - in which case you might decide to "accept" one of the answers given (with the little check mark).
Are you using the latest version of my code (updated 2 hours ago) - the "simple code to test in your Javascript"? The variable goodTime should have just the right answer in it... Two tricks - I changed the expression very slightly (added ?:) and explicitly access m[0] for the answer.
Cannot upvote this one enough! Thanks for the solution and the cool site Rubular
|
0

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

Comments

0

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...

1 Comment

Note that 23.75 is valid - I think OP is using "decimal time" not HH:MM

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.