views:

811

answers:

3

Stuggling a little bit with the RegEx, I've got 4 codes in a string

CODE4:CODE3:CODE2:CODE1

each code is optional apart from CODE1

So I could have ab:bc:de:fg

or

bc::fg

of

ab:::fg

In each case of the above CODE1 = fg dnd for the dear life of me I can't work out the RegEX

Would be easy to do as a standard string parse, but unforunatly because of buisness objects in needs to be done via regex :-( and return via a vb.net RegEX.matche,groups("Code1") fg (I hope that makes sense)

Thanks in advance for any help

Ended up with a bit of RegEx that does the job, bit messy but it works

(^(?<code1>[\w]*)$)|(^(?<code2>[\w]*):(?<code1>[\w]*)$)|(^(?<code3>[\w]*):(?<code2>[\w]*):(?<code1>[\w]*)$)|(^(?<code4>[\w]*):(?<code3>[\w]*):(?<code2>[\w]*):(?<code1>[\w]*)$)

Ta all

+3  A: 

There's no need to use a regular expression here.

I don't know what language you're using, but split the string on ':' and you'll have an array of codes.

If you really just want to validate whether a string is valid for this then

/(\w*:){0,3}\w+/

matches your description and the few examples you've given.

Gareth
I would prefer [^:]+ to \w* personally, other than that looks good
Jeff Atwood
Work fine and matches all variants of the code, but I can't see how to extract via regex.matches,groups the individual parts (code1)I've updated the question as to why I need to do it like this
spacemonkeys
@Jeff Atwood: I don't see the advantage of [^:] over \w if the codes are alphanumeric, and the + instead of * is wrong here, since we can have empty fields.
PhiLho
@PhiLho: the OP didn't say the codes are always alphanumeric. All we can reasonably assume is that they can't contain colons. And the + is because leading fields are optional if they're empty.
Alan Moore
A: 

I'm not sure why you have to match the codes right to left. Simply use a regular expression to pick apart the string:

/(.*):(.*):(.*):(.+)/

and then you have CODE1 in $4, CODE2 in $3, CODE3 in $2, CODE4 in $1.

Avi
That works fine withab:cd:ef:ghbut notgh or cd::gh (where gh = code 1)
spacemonkeys
A: 

(CODE1)?:(CODE2)?:(CODE3)?:CODE4 would work - if the leading : don't matter. Otherwise, if you can't have leading colons, enumerate:

`(CODE1:(CODE2)?:(CODE3)?:|CODE2:(CODE3)?:|CODE3)?CODE4

There's nothing special about the fact that the right-most part is mandatory, and the left-most parts aren't.

MSalters