regular expression for matching a specific decimal number
I need to verify if the answer entered by a user is correct for an online quiz.
The answer is supposed to be a decimal number that may be entered in a number of different ways.开发者_运维问答 For example,
0.666666...
could match
.66
.67
.66666
.667
0.6667
etc.
Basically, I want to ignore rounding, precision, and preceding zeros. The examples I found are for matching any decimal numbers.
thanks,
RT
edits -
I am writing a quiz for WebCT. It allows three options for matching correct answer: "equals", "contains" and "regular expression". I believe WebCT is Java based. But I couldn't be sure as to what flavor of regular-expression it uses. I can ask users to provide correct answer upto three decimal places. In which case correct answers could be one of the following four: 0.666 0.667 .666 .667
For a decimal representation of a fraction, you have a nice normal form: it will consist of a finite decimal, followed by a sequence of decimal digits that repeat infinitely. So, e.g., 1/7 is "0." followed by infinitely many repetitions of "142857". There's a sense (see below) in which these fractional decimal representations are the only ones that can be represented by a regular expression.
The technique for these is that you represent these with a tree, where the base part is a series of optional bracketed expressions, with alternatives to express rounding up so 8.19 would be given 8(.(2|(19?)?)?
, and then repeating part starred, and then a section that gives all the ways that the repeating part may be rounded.
E.g.: 1/7 is given by 0?.(142857)*(1(4(3|2(8(6|57?)?)?)?)?)?
.
Aside
The sense in which regular expressions can express only fractions is the following. Say that a formal expression describes a decimal representation if its language is all the finite decimal prefixes of the number, so an expression for 2/3 must have as its language 0, 0.6, 0.66, 0.666, &c. A finite state machine that accepts only prefixes in this way must repeat itself, and thus be a fraction.
So no regular expression accepts, say sqrt(2)
exactly.
You may be better off simply converting the user-entered string into a number (using whatever language facilities you have, lke C's atof
), then just ensuring it's close enough (within a set margin of error), or even by specifying a minimum and maximum (say 0.6 and 0.67).
But, if you really want a regex:
^0*\.6+7?$
should do the trick for that particular number.
That's zero of more of 0
followed by .
, then one or more 6
characters and an optional 7
.
To enforce at least two decimal places as requested in a comment, you could use:
^0*\.6+[67]$
That forces it to end in a 6
or 7
and have one or more 6
characters preceding that.
/^0*\.6+7?\.*$/
Broken down:
^0*
<- optional zeroes
\.
<- escaped decimal
6+
<- at least one 6, or more
7?
<- optional 7
\.*$
<- ellipsis, at least 0 or more
It doesn't sound like you want regular expressions for this. They are purely textual and have no notion of "decimal numbers that can be expressed in more than one way."
I think what you should do is convert the user's answer to a floating-point data type in whatever programming language you're working in, and subtract it from the correct answer. The result is the error in the student's answer. If the result is less than some threshold, say +0.06, then consider it correct. That way, 0.6, 0.66, 0.667, 0.6667, etc., will all be considered correct.
精彩评论