Регулярное выражение в ruby ​​для строк с несколькими шаблонами

У меня есть строка с необязательными подстроками, и я искал / работал / для регулярного выражения с захватами имен, единственное регулярное выражение для всех, если это возможно.

в рублях

Пожалуйста помоги,

образцы строк:

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

Я провел почти день в Google и Stackru, чтобы получить единственное регулярное выражение для всех вышеупомянутых шаблонов строк.

2 ответа

Решение

Предположения:

  • Место и время начинаются с @, а также @ больше нигде не появляется.
  • Дата начинается с on окружены обязательными белыми пространствами, и on больше нигде не появляется.
  • Задача обязательна.
  • Место и дата не являются обязательными и не зависят друг от друга.
  • Время появляется только тогда, когда есть дата.
  • Задача, местоположение, дата, время отображаются только в этом порядке.

Кроме того, следует считать само собой разумеющимся, что механизм регулярных выражений является oniguruma, так как упоминается именованный захват.

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

Чтобы регулярное выражение выполняло эту работу, необходимо сделать некоторые предположения. Задачи не должны включать " @ " или "вкл", например, но их может быть больше.

Чтобы соответствовать любому символу, кроме первого пробела для " @ " или "вкл", я бы использовал (?! @ | on ).Таким образом, вы можете найти задачу, используя (((?! @ | on ).)+), Затем следует необязательное местоположение с префиксом " @ ": (?: @ ((?:(?! on ).)+))?, Обратите внимание, что местоположение не должно включать "вкл" здесь.

После этого есть дополнительная дата с дополнительным временем: (?: on ((?:(?! @ ).)+)(?: @ (.+))?)?, Все вместе:

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

Это будет иметь задачу, местоположение, дату и время в первых четырех группах захвата. Смотрите здесь: http://regexr.com/?2tnb3

Другие вопросы по тегам