tags:

views:

80

answers:

6

I am brand new to using RegEx's and need a bit of a jump start to get the ball rolling. The RegEx I need is, hopefully, pretty simple.

All it needs to do is verify that the text entered follows the following format:

00.000 (2 digits, a period, 3 digits).

Any advice on the the RegEx itself and how to implement would be greatly appreciated!

EDIT: Thanks for all the suggestions, everyone! All is well...

+3  A: 

Try:

\d\d\.\d\d\d

Equally:

\d{2}\.\d{3}

And if at some point, you want to introduce say at minimum 1 digit but accept 2 before the decimal point, you can specify lower and upper bound inside the curly brackets too:

\d{1,2}\.\d{3}

Would match 1.273 but also 17.920 for instance.

Wim Hollebrandse
Actually, it should be \d\d\.\d\d\d If you don't escape the period, you will match 2 digits, any character, 3 digits.
Jeff B
That's what I had, but using it with <code> formatting seems to get eaten by SO HTML encoding. Edited it to use pre formatting which seems to work fine.
Wim Hollebrandse
Don't you love dealing with multiple escape levels?
Jeff B
You can just indent code with 4 spaces, or select it and click the "code" button in the toolbar, or select it and perss Ctrl+K.
Joey
Thanks Johannes - wasn't aware of that yet! I keep farting around typing the formatting tags in. ;-)
Wim Hollebrandse
+7  A: 

I think this is the pattern you're looking for:

\d\d\.\d\d\d

or

\d{2}\.\d{3}
Joseph
+2  A: 

\d{2}\.\d{3}
A short explanation:
\d will match any digit-character and the braces indicate how many times it has to be matched.
So, \d{2} means 2 digits right after each other.
A dot in a regex expression means 'match any character except a new line' (unless you added a special flag which will also match newlines), so to match an actual dot-character we have to escape the dot-operator by prepending a backslash. \.
And a recommendation for an application: RegExr

Jeroen Pelgrims
Or UltraPico's Expresso. :)
tommieb75
Oooops....the address is http://www.ultrapico.com/Expresso.htm
tommieb75
A: 

(?<firstPart>\d{2})\.(?<lastPart>\d{3}) Should do it, then if you wish, you can then interrogate the Groups["firstPart"] or Groups["lastPart"] to obtain the actual captured value contained within the match. Hope this helps. Tom.

tommieb75
+1  A: 

A different version:

\d{2}.\d{3}

Another version that will allow minimum of 1-2 digits and 1-3 decimals:

\d{1,2}.\d{1,3}

JookyDFW
A: 

If you want to implement it, the final state machine would be just fine. For example:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define FSM
#define STATE(x)      s_##x :
#define NEXTSTATE(x)  goto s_##x

int test_input(const char *str) {
  if (strlen(str) != 6)
    return 1;

  FSM {
    STATE(q0) { /* first digit */
      if (isdigit(*str++)) NEXTSTATE(q1);
      else return 1;
    }

    STATE(q1) { /* second digit */
      if (isdigit(*str++)) NEXTSTATE(q2);
      else return 1;
    }

    STATE(q2) { /* dot */
      if (*str++ == '.') NEXTSTATE(q3);
      else return 1;
    }

    STATE(q3) { /* third digit */
      if (isdigit(*str++)) NEXTSTATE(q4);
      else return 1;
    }

    STATE(q4) { /* fourth digit */
      if (isdigit(*str++)) NEXTSTATE(q5);
      else return 1;
    }

    STATE(q5) { /* fifth digit */
      if (isdigit(*str)) return 0;
      else return 1;
    }
  }

  return 0;
}

int main(void) {
  char *input1 = "38.901";
  char *input2 = "38,901";
  int retval = test_input(input1);
  printf("%s\n", (retval)?"fail": "ok");
  retval = test_input(input2);
  printf("%s\n", (retval)?"fail": "ok");
  return 0;
}

There is formal theory for transforming regular expressions into finite state machines, but I think this would be too complex for you. If you are parsing some more complicated input and if you do that often, you should learn EBNF form and learn some parser generator like Bison (C, C++), Parsec or Happy (Haskell) and so on.

Martin Kopta