Skip to content
Advertisement

Regular expression for digits, decimals, and fractions

How can I create a regex that allows whole numbers, decimals, fractions, and fractions with decimals? The string can also have optional text, only at the end. So far I have this:

const re = /^d*.?d*/?d*.?d*[a-z]*$/gi;

This allows double decimals in a whole number(ie: ‘23.23.23’), which I do not want. Can I modify this regex to allow two decimal points only if it is separated by a ‘/’?

Here are some examples that can pass:

  • 23.23/100km
  • 1/3
  • .23km
  • 1.mi
  • 1.2/2.1kg

Some examples that shouldn’t pass:

  • 1a3km
  • 12.12.12
  • 1.2.3/12.13km
  • 12km/12.44km

Advertisement

Answer

Use

^(?!.*d+(?:.d+){2})d*.?d*/?d*.?d*[a-z]*$

See proof. This expression disallows three numbers that have a period between one another thanks to (?!.*d+(?:.d+){2}) negative lookahead.

EXPLANATION

--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
    .*                       any character except n (0 or more times
                             (matching the most amount possible))
--------------------------------------------------------------------------------
    d+                      digits (0-9) (1 or more times (matching
                             the most amount possible))
--------------------------------------------------------------------------------
    (?:                      group, but do not capture (2 times):
--------------------------------------------------------------------------------
      .                       '.'
--------------------------------------------------------------------------------
      d+                      digits (0-9) (1 or more times
                               (matching the most amount possible))
--------------------------------------------------------------------------------
    ){2}                     end of grouping
--------------------------------------------------------------------------------
  )                        end of look-ahead
--------------------------------------------------------------------------------
  d*                      digits (0-9) (0 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  .?                      '.' (optional (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  d*                      digits (0-9) (0 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  /?                      '/' (optional (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  d*                      digits (0-9) (0 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  .?                      '.' (optional (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  d*                      digits (0-9) (0 or more times (matching
                           the most amount possible))
--------------------------------------------------------------------------------
  [a-z]*                   any character of: 'a' to 'z' (0 or more
                           times (matching the most amount possible))
--------------------------------------------------------------------------------
  $                        before an optional n, and the end of the
                           string
Advertisement