1

i have a string with optional substrings and i was looking/working for/on regular expression with names captures, a single regular expression for all if possible.

in RUBY

Please help,

sample strings:

string1 = bike wash #a simple task
string2 = bike wash @ bike point # a simple task with location
string3 = bike wash @ bike point on 13 may 11 # task with location and date
string4 = bike wash @ bike point on 13 may 11 @ 10 AM # task with location, date and time
string5 = bike wash on 13 may 11 @ 10 AM # task with date and time without location
string6 = bike wash on 13 may 11 # task and date

i have spent almost a day in google and stackoverflow to get a single regular expression for all the above pattern of strings.

3
  • Two things. One, please show what you've tried. Two, the rest of your question isn't clear. Do you want dictionaries as output? Do you expect other date formats or is this list exhaustive? Commented May 9, 2011 at 6:52
  • @phooji (one) these were the regex i was trying and the fact that am newbie in ruby and regex /(?<task>.*) ( @ (?<location>.*)? ) on (?<date>.*) ( @ (?<time>.*)? ) /x /(?<task>.*) ( @ (?<location>.*)? ) on (?<date>.*) ( @ (?<time>.*) ) /x (two) am not expecting other date formats and thats the list, i just had those 6 patterns in mind. Commented May 9, 2011 at 8:52
  • is there a way to accept both the answers? i go with the first one given by @sawa, because its simple, easily readable and also has named captures (<task> etc) Commented May 9, 2011 at 9:11

2 Answers 2

4

Assumptions:

  • Location and time start with @, and @ appears nowhere else.
  • Date starts with on surrounded with obligatory white spaces, and on appears nowhere else.
  • Task is obligatory.
  • Location and date are optional and independent of one another.
  • Time appears only when there is date.
  • Task, location, date, time only appear in this order.

Also, it should be taken for granted that the regex engine is oniguruma since named capture is mentioned.

regex = /
  (?<task>.*?)
  (?:\s*@\s*(?<location>.*?))?
  (?:\s+on\s+(?<date>.*?)
    (?:\s*@\s*(?<time>.*))?
  )?
\z/x

string4.match(regex)
# => #<MatchData
  "bike wash @ bike point on 13 may 11 @ 10 AM"
  task:     "bike wash"
  location: "bike point"
  date:     "13 may 11"
  time:     "10 AM"
>
Sign up to request clarification or add additional context in comments.

1 Comment

sawa, thank you so much for the regex, ur solution too works perfect for all the patterns.
2

For regular expression to do this job, some assumptions need to be made. Tasks should not include " @ " or " on ", e.g, but there may be more.

To match any character but the first space for " @ " or " on ", I'd use (?! @ | on ). So you could find the task using (((?! @ | on ).)+). This is followed by an optional location, prefixed with " @ ": (?: @ ((?:(?! on ).)+))?. Note that the location should not include " on " here.

Following that, there is an optional date with an optional time: (?: on ((?:(?! @ ).)+)(?: @ (.+))?)?. All together:

((?:(?! @ | on ).)+)(?: @ ((?:(?! on ).)+))?(?: on ((?:(?! @ ).)+)(?: @ (.+))?)?

This will have task, location, date and time in the first four capturing groups. See here: http://regexr.com?2tnb3

2 Comments

thank you so much for that regex, works perfectly for all the 6 string patterns mentioned above
regex with names /(?<task>.(?:(?! @ | on ).)+)(?: @ (?<location>(?:(?! on ).)+))?(?: on (?<date>(?:(?! @ ).)+)(?: @ (?<time>.+))?)?/x

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.