1

I look for a regular expression to support double number with just one fraction part which ranges between 0.1 to 999.9

It means following values are not allowed:

0
0.0 // less than lower bound
0.19 // fraction part is 2 digits, right '9' is extra
94.11 // fraction part is 2 digits, right '1' is extra
999.90 // fraction part is 2 digits, '0' is extra
9.0 // should be 9 or 9.1, 9.0 is wrong
1000 // is higher than upper bound

allowed ones:

1.1
55.5
999.9

My regular expression is:

(^(\.[1-9])?$|(^[1-9][0-9]{0,2}?(\.[1-9])?$))$

Which doesn't support 0.1 to 0.9 and extra zeros like 99.000 and 99.0

Test steps: In your browser console:

var reg = new RegExp(/(^(\.[1-9])?$|(^[1-9][0-9]{0,2}?(\.[1-9])?$))$/);
reg.test(12);

Any help appriciated

Tibos
  • 27,507
  • 4
  • 50
  • 64
Yaser Moradi
  • 3,267
  • 3
  • 24
  • 50
  • 2
    `reg.test("12");` because you're testing strings, not numbers. – Halcyon Oct 28 '13 at 10:43
  • 1
    Do you want to test numbers or strings? Because it makes no difference in numbers how many zeros they have in the end of the fraction part. E.g. `12.1 === 12.1000`. – matewka Oct 28 '13 at 11:10
  • From reading the answers, there seems to be a lot of confusion around your requirements, @YasserMoradi. Perhaps you could take a step back and explain what your goal is? – Mark Reed Oct 28 '13 at 11:20
  • @MarkReed I've an validation engine that uses validations based on regular expressions and|or schematron, and tests data on both client side javaScript and server side(.NET), We are extending that, but for now, we should use this method. – Yaser Moradi Oct 28 '13 at 11:46
  • I get that you may have to use regexes instead of arbitrary code to do the validation, but why do you have to be so specific about the form of the number? Why is "9" OK but "9.0" bad, etc? – Mark Reed Oct 28 '13 at 12:39
  • @MarkReed I'm agree with you, but I'm responsible for the framework and validation engine itself, The business analyzers and developers are doing on their own. – Yaser Moradi Oct 28 '13 at 13:23
  • in case it helps someone, I created a javascript tool that creates a highly optimized regex from two inputs (min/max) https://github.com/jonschlinkert/to-regex-range – jonschlinkert Apr 21 '17 at 10:18

7 Answers7

3

Following regex should for you:

^[1-9]([0-9]{1,2})?(\.[1-9])?$
Amit Dash
  • 584
  • 8
  • 21
anubhava
  • 761,203
  • 64
  • 569
  • 643
2

I guess this is the most accurate:

/^(0\.[1-9]|[1-9][0-9]{0,2}(\.[1-9])?)$/

Note that you don't need the RegExp constructor when working with regex literals:

 re = /^(0\.[1-9]|[1-9][0-9]{0,2}(\.[1-9])?)$/
 a = [0, 0.1, 123, 123.4, '00.1', 123.45, 123456, 'foo']
 a.map(function(x) { console.log(x, re.test(x)) })

0 false
0.1 true
123 true
123.4 true
00.1 false
123.45 false
123456 false
foo false
georg
  • 211,518
  • 52
  • 313
  • 390
2

Thought I would add an alternative way to accomplish this with a node.js javascript library that I created for generating these ranges automatically.

To use the library, you would first need to install it using npm:

$ npm install --save to-regex-range

Then add the library to your application with the following line of code

var toRegexRange = require('to-regex-range');

The main export is a function that takes two integers: the min value and max value (formatted as strings or numbers).

Examples

console.log(toRegexRange('111', '555'));
//=> 11[1-9]|1[2-9][0-9]|[2-4][0-9]{2}|5[0-4][0-9]|55[0-5]

console.log(toRegexRange('5', '5'));
//=> 5

console.log(toRegexRange('5', '6'));
//=> [5-6]

console.log(toRegexRange('51', '229'));
//=> 5[1-9]|[6-9][0-9]|1[0-9]{2}|2[0-2][0-9]

console.log(toRegexRange('29', '51'));
//=> 29|[3-4][0-9]|5[0-1]

console.log(toRegexRange('1', '100000'));
//=> [1-9]|[1-9][0-9]{1,4}|100000

The readme has more documentation and examples.

jonschlinkert
  • 10,872
  • 4
  • 43
  • 50
1

How about this:

var reg = new RegExp(/^\d{1,3}\.[1-9]$/);

It works with all the positive and negative cases you supplied.

acfrancis
  • 3,569
  • 25
  • 21
  • fractional part should be optional. – Mark Reed Oct 28 '13 at 11:18
  • Your answer was helpful, but was not complete, I try to improve that. Thanks – Yaser Moradi Oct 28 '13 at 11:23
  • @Mark Reed, I agree with you in the general case but it really depends what the asker is trying to do. I'm trying not to second-guess his requirements. – acfrancis Oct 28 '13 at 11:26
  • I wasn't stating a personal belief, @acfrancis. Based on the post, integers with no fractional part ("9") are allowed, while integral values with a spurious decimal attached ("9.0") are not. See 6th example in the "incorrect" list, with associated comments. – Mark Reed Oct 28 '13 at 12:38
  • I'm sure you're right. Reading the whole thing again, the requirements still seem odd to me. "9.0" is a good decimal number where I come from. That's a joke, btw. – acfrancis Oct 28 '13 at 12:45
0

You don't need regex at all. Some simple (and much faster than regex) math equeations will do the job:

function testNumber(number) {
    if (number < 0.1 || number > 999.9 || parseInt(10*number) != 10*number || number == parseInt(number))
        return false;

    return true;
}

alert( testNumber(12) );

In the if statement we check 4 things:

  • is the number lower than 0.1
  • is the number higher than 999.9
  • does the number have more than one digit in thefraction part
  • is the number an integer (no digits in fraction part)

If any of the conditions above is true then te function returns false.

matewka
  • 9,912
  • 2
  • 32
  • 43
  • But `number == parseInt(number)` eliminates all integral values. Those aren't disallowed, they just need to not have a .0 tacked on. If I'm reading OP's rules right, anyway. The point is, there are restrictions on the form of the number that seem to go beyond its value and that it is a legal float. – Mark Reed Oct 28 '13 at 11:03
  • @MarkReed, I don't think so. Look at the 6th example in OP's __disallowed__ numbers (9.0). – matewka Oct 28 '13 at 11:03
  • Yes. But per OP, "12.1" is allowed, and "12.10000" is not. – Mark Reed Oct 28 '13 at 11:06
  • Right. The string "9.0" is disallowed. Look at comment: "should be 9" – Mark Reed Oct 28 '13 at 11:07
  • You're right, I didn't notice that. Now I am totally confused. The OP wants to check numbers but he doesn't assume that leading zeros doesn't matter in numbers. – matewka Oct 28 '13 at 11:08
  • Thanks for your solution, but I've to use regular expression because of limitations of our validation engine. – Yaser Moradi Oct 28 '13 at 11:32
0

You are better off first checking if the number is a double using Regex and then checking separately if it falls inside the range. Having business logic obfuscated by something like Regex means your code is harder to maintain. And if you ever have to update your business logic to other numbers, you'll have a hard time.

[-+]?([0-9]*\.[1-9]|[0-9]+)

the above Regex validates a floating point. After that, you can just ParseFloat and compare for the rest of the logic.

Nzall
  • 3,439
  • 5
  • 29
  • 59
  • @YasserMoradi Are you sure? I used http://www.regular-expressions.info/javascriptexample.html to verify it, and the above regex gives a match for 1.11 – Nzall Oct 28 '13 at 12:38
  • And I just realized that you want 1 decimal at most. give me a moment to fix it. – Nzall Oct 28 '13 at 12:40
0

While you shouldn't use Regexp to compare ranges of numbers, here is one that should work for your case:

/^(?:[1-9]\d{0,2}(?:\.[1-9])?)|(?:0\.[1-9])$/

Example (unanchored): http://regex101.com/r/dY5pL3

Tibos
  • 27,507
  • 4
  • 50
  • 64