tags:

views:

83

answers:

3

I have a simple problem, yet i am unable to solve this. Either my string has a format ID: dddd, with the following regular expression:

/^ID: ([a-z0-9]*)$/

or as follows: ID: 1234 Status: 232, so with the following regular expression:

/^ID: ([a-z0-9]*) Status: ([a-z0-9]*)$/

Now i want to make one regular expression that can handle both. The first thing i came up with was this:

/^ID: ([a-z0-9]*)$|^ID: ([a-z0-9]*) Status: ([a-z0-9]*)$/

It matches, but i was looking into conditional regular expressions, and was thinking that something should be possible along the lines of (pseudo-codish)

if the string contains /Status:/
    /^ID: ([a-z0-9]*)$/
else
    /^ID: ([a-z0-9]*) Status: ([a-z0-9]*)$/

only, i can't get this expressed correctly. I thought i should be using /?=/ but have no clue how. Something like

/((?=Status)^ID: ([a-z0-9]*) Status: ([a-z0-9]*)$|^ID: ([a-z0-9]*)$/

but that doesn't work.

Can you help?

+3  A: 

You need a .* in your lookahead: (Rubular)

/(?=.*Status)^ID: ([a-z0-9]*) Status: ([a-z0-9]*)$|^ID: ([a-z0-9]*)$/

However, for your specific example you don't need a lookahead. You can just use the ? quantifier instead: (Rubular)

/^ID: ([a-z0-9]*)(?: Status: ([a-z0-9]*))?$/
Mark Byers
Thank you for the link to the documentation, and the two examples.
nathanvda
+4  A: 

You're looking for ^ID: (\d+)(?: Status: (\d+))?$

edit: Since the question is tagged Ruby it's worth mentioning that according to both this question and this flavour-comparison, Ruby doesn't do conditional regex.

http://www.regular-expressions.info is a great source on the subject.

CharString
@jerhinesmith: the title mentions conditional re, but the problem at hand can be solved without them. I use (?:<pattern>) to make the pattern non-matching. That way $1 and $2 will contain the matched numbers of which the latter is optional.
CharString
@CharString, I agree, and that makes perfect sense, but if Ruby doesn't support true 'conditional regex', then that should at least be pointed out in the answer. I'm thinking more about future visitors to this question (from google, etc.) and at first glance, it would seem that while you're solving the problem, there's no mention as to *why* they should use this method and *not* use conditional regex.
jerhinesmith
@jerhinesmith: You're right. Edited accordingly.
CharString
@CharString Thanks! Upvoted.
jerhinesmith
That flavor comparison is based on Ruby's old regex flavor, but the new one (Oniguruma) doesn't support conditionals either.
Alan Moore
+1  A: 

Interestingly, according to this question, Ruby 1.8/1.9 does not support conditional regular expressions.

Have you (or any of the answerers) read otherwise? If so, it might be helpful to update the linked question so that it no longer gives incorrect information.

jerhinesmith
Regex assertions/lookarounds and regex conditionals are two different things.
polygenelubricants
Isn't the question about regex conditionals? I guess I'm not sure I see your point. This question and the linked question both seem to use the general format `(?(predicate)yes-pattern|no-pattern)`, so unless I'm missing something, they very much are related.
jerhinesmith
Ha! That would explain things :)
nathanvda
But, the documentation http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html#UJ clearly states otherwise.
nathanvda
@nathanvda: That page appears to refer to Ruby's old regex flavor, but conditionals aren't supported in the new flavor either. It's mentioned in section A-3 of the Oniguruma doc: http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt
Alan Moore
Thank you, i stand corrected :) I was actually completely wrong.
nathanvda