tags:

views:

100

answers:

4

I'm trying to create a RegEx that matches the 3 patterns listed above. I can somewhat create a working RegEx for any of those 3 but my problem is creating one that works with all 4 of those. The allowed values are below, where D is any digit and the '.' is never present as a trailing character (i.e. DDD. wouldn't be valid). Also the V and E refer to those specific characters.

  • ddd
  • ddd.d
  • ddd.dd
  • Vdd
  • Vdd.d
  • Vdd.dd
  • Eddd
  • Eddd.d

Everything else should be invalid, such as:

  • d
  • dd
  • V
  • Vd
  • Vdd. (trailing '.')
  • E
  • Ed
  • Edd

I'm not great with RegEx, but I could describe part of this pattern for the entries that start with V as the following:

V[0-9]{2,2}(\.[0-9]{1,2})?

I could write very similar statements for the all digit portion of entires and E prefix portion of entries. The problem is how to combine all 3 into a RegEx that doesn't make my head spin to read. What's a good RegEx to match all 3 patterns?

EDIT: I forgot to include the format Vdd.dd

+1  A: 
(E\d|(V|\d))\d{2,2}(\.\d)?(?(2)\d?|)

E with one digit, or V, or a single digit, followed by two digits, then the usual decimal stuff.

E has to have three non decimal digits, V has to have 2, and digits by them selves have to have three.

If the V or single digit match at the start (I.E. Not 'E') then an extra digit is allowed on the rear.

Grant
E and V can only be followed by 1 digit past the decimal (at least it seems that way from the post). This allows for Eddd.dd
quadelirus
Fixed it. Now Eddd.d is disallowed.
Grant
+1  A: 
(\d{3}(\.\d{1,2})?)|(V\d{2}(\.\d{1,2})?)|(E\d{3}(\.\d)?)

EDIT: Some explanation: I just matched all 3 different formats:

\d{3}(\.\d{1,2})?

says three digits optionally followed by a period matched with 1 or 2 digits.

V\d{2}(\.\d{1,2})?

says V followed by two digits with optional period and one or two digits

E\d{3}(\.\d)?

says three digits followed by an optional period with a single digit

Then I just surrounded each with () and combined them all with | (or).

quadelirus
put four spaces on the line with the backslash to make it treat it as code instead of MarkDown
Jared Updike
this looks very close to what i need - i forgot to include Vdd.dd as i mention in the edited post but otherwise this looks great!
James Cadd
Should be fixed for that case now.
quadelirus
I was wrong. Now it is fixed--I had put \d){1,2} when I meant \d{1,2})
quadelirus
BTW I think you can spend a lot of time really trying to boil down a regexp into one expression but often it suffices to cover the basic cases and or them together with |--and many times this is much easier to figure out what its doing down the road when you have to modify the code three months after not touching it.
quadelirus
One more mistake on there-- for the second case add a ?
quadelirus
Should be correct now.
quadelirus
+1  A: 

Nothing wrong with having three different regular expressions, is there?

\d{3}(.\d{1,2)?
V\d{2}(.\d)?
E\d{3}(.\d)?

And this will probably be more maintainable in the future.

Lee
i'm using the regex for the mask field of devexpress silverlight controls toolkit, it only accepts a single string. but yes, otherwise i'd like to keep them separate.
James Cadd
+1  A: 

If Eddd would be invalid it would be much easier:

[EV\d]\d{2}(\.\d{0,2})?

Similarly if Vddd was valid:

[EV\d]\d{2,3}(\.\d{0,2})?

Matching exactly what you have is a bit harder:

(\d{3}(\.\d{1,2})?)|(V\d{2}(\.\d)?)|(E\d{3}(\.\d)?)

Make sure you test for exact match otherwise things like

V123.1

Will match as

V12
Adam W
Thank you for the explanation, it's very helpful. Yes if those strange cases didn't exist my life would be a bit easier ;)
James Cadd
Had to edit slightly for my extra case that i forgot but this one completely works. ty. (\d{3}(\.\d{1,2})?)|(V\d{2}(\.\d{1,2})?)|(E\d{3}(\.\d)?)
James Cadd