简体   繁体   中英

regular expression in ruby for strings with multiple patterns

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.

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"
>

For regular expression to do this job, some assumptions need to be made. Tasks should not include " @ " or " on ", eg, 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM