Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make at least one group mandatory

Tags:

java

regex

I have a question about regexes in Java, though I think this might apply to other languages as well.

I have a regex to parse time from a field where user may enter something like 4d 8h 42m. Of course, I want to make it as flexible as possible, so that user should not be obliged to type all numbers (and enter a mere 15h for instance).

My regex is quite satisfactory concerning that point: (?:([\d]+)d)?[\s]*(?:([\d]+)h)?[\s]*(?:([\d]+)m)?

Now my problem is that it will also match an empty string, though I would like it to ensure that at least one time-unit is filled.

The current solution would be to arbitrary choose one of them to be mandatory, but I am not satisfied with it since mandatory field is what I am trying to avoid.

Also, making an or does not suit me, since I would have to test groups when parsing the regex afterwards, instead of just accessing group(1) for days, group(2) for hours, ... (This is what I think of when speaking of an or : (?:([\d]+)d[\s]*(?:([\d]+)h)?[\s]*(?:([\d]+)m)?|(?:([\d]+)d)?[\s]*([\d]+)h[\s]*(?:([\d]+)m)?|(?:([\d]+)d)?[\s]*(?:([\d]+)h)?[\s]*([\d]+)m), to be understood as days mandatory or hours mandatory or minutes mandatory).

So how could I modify my regex to make sure that at least one of my now-non-capturing group is not empty, be it days, hours or minutes?

like image 810
Chop Avatar asked Nov 20 '12 07:11

Chop


1 Answers

You can use a look-forward assert to ensure that at least one of d h or m appears.

(?=.*[mhd])(?:(\d+)d)?\s*(?:(\d+)h)?\s*(?:(\d+)m)?
like image 159
OmnipotentEntity Avatar answered Oct 08 '22 20:10

OmnipotentEntity