nickel 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Rakefile +5 -1
- data/lib/nickel/construct.rb +31 -36
- data/lib/nickel/construct_finder.rb +442 -360
- data/lib/nickel/construct_interpreter.rb +50 -52
- data/lib/nickel/nlp.rb +18 -21
- data/lib/nickel/nlp_query.rb +471 -471
- data/lib/nickel/nlp_query_constants.rb +1 -1
- data/lib/nickel/occurrence.rb +7 -8
- data/lib/nickel/version.rb +1 -1
- data/lib/nickel/zdate.rb +86 -77
- data/lib/nickel/ztime.rb +58 -54
- data/spec/lib/nickel/construct_spec.rb +66 -0
- data/spec/lib/nickel/nlp_spec.rb +7 -7
- data/spec/lib/nickel/occurrence_spec.rb +20 -21
- data/spec/lib/nickel/zdate_spec.rb +49 -29
- data/spec/lib/nickel/ztime_spec.rb +174 -158
- data/spec/lib/nickel_spec.rb +687 -609
- data/spec/spec_helper.rb +2 -2
- metadata +4 -2
@@ -2,9 +2,7 @@ require_relative 'occurrence'
|
|
2
2
|
require_relative 'construct'
|
3
3
|
|
4
4
|
module Nickel
|
5
|
-
|
6
5
|
class ConstructInterpreter
|
7
|
-
|
8
6
|
attr_reader :occurrences, :constructs, :curdate
|
9
7
|
|
10
8
|
def initialize(constructs, curdate)
|
@@ -31,19 +29,20 @@ module Nickel
|
|
31
29
|
end
|
32
30
|
|
33
31
|
private
|
32
|
+
|
34
33
|
def initialize_index_to_type_map
|
35
34
|
# The @index_to_type_map hash looks like this: {0 => :date, 1 => :timespan, ...}
|
36
35
|
# Each key represents the index in @constructs and the value represents that constructs class.
|
37
36
|
@index_to_type_map = {}
|
38
|
-
@constructs.each_with_index do |c,i|
|
37
|
+
@constructs.each_with_index do |c, i|
|
39
38
|
@index_to_type_map[i] = case c.class.name
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
when 'Nickel::DateConstruct' then :date
|
40
|
+
when 'Nickel::TimeConstruct' then :time
|
41
|
+
when 'Nickel::DateSpanConstruct' then :datespan
|
42
|
+
when 'Nickel::TimeSpanConstruct' then :timespan
|
43
|
+
when 'Nickel::RecurrenceConstruct' then :recurrence
|
44
|
+
when 'Nickel::WrapperConstruct' then :wrapper
|
45
|
+
end
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
@@ -52,27 +51,27 @@ module Nickel
|
|
52
51
|
# Determine user input style, i.e. "DATE TIME DATE TIME" OR "TIME DATE TIME DATE".
|
53
52
|
# Determine user input style, i.e. "DATE TIME DATE TIME" OR "TIME DATE TIME DATE".
|
54
53
|
case (@index_to_type_map[0] == :wrapper ? @index_to_type_map[1] : @index_to_type_map[0])
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
54
|
+
when :date then @user_input_style = :datetime
|
55
|
+
when :time then @user_input_style = :timedate
|
56
|
+
when :datespan then @user_input_style = :datetime
|
57
|
+
when :timespan then @user_input_style = :timedate
|
58
|
+
when :recurrence then @user_input_style = :datetime
|
59
|
+
else
|
60
|
+
# We only have wrappers. It doesn't matter which user style we choose.
|
61
|
+
@user_input_style = :datetime
|
63
62
|
end
|
64
63
|
end
|
65
64
|
|
66
65
|
def initialize_arrays_of_construct_indices
|
67
|
-
@dci
|
66
|
+
@dci, @tci, @dsci, @tsci, @rci, @wci = [], [], [], [], [], []
|
68
67
|
@index_to_type_map.each do |i, type|
|
69
68
|
case type
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
69
|
+
when :date then @dci << i
|
70
|
+
when :time then @tci << i
|
71
|
+
when :datespan then @dsci << i
|
72
|
+
when :timespan then @tsci << i
|
73
|
+
when :recurrence then @rci << i
|
74
|
+
when :wrapper then @wci << i
|
76
75
|
end
|
77
76
|
end
|
78
77
|
end
|
@@ -127,7 +126,7 @@ module Nickel
|
|
127
126
|
# meaning move forward.
|
128
127
|
if @user_input_style == :datetime then index + 1
|
129
128
|
elsif @user_input_style == :timedate then index - 1
|
130
|
-
else
|
129
|
+
else fail 'ConstructInterpreter#move_time_map_index says: @user_input_style is not valid'
|
131
130
|
end
|
132
131
|
end
|
133
132
|
|
@@ -138,7 +137,7 @@ module Nickel
|
|
138
137
|
else
|
139
138
|
# There are times for this date, use them for any indices marked as inherit_on.
|
140
139
|
# Then clear the inherit_on array.
|
141
|
-
inherit_on.each {|k| @sorted_time_map[k] = @sorted_time_map[date_index]}
|
140
|
+
inherit_on.each { |k| @sorted_time_map[k] = @sorted_time_map[date_index] }
|
142
141
|
inherit_on = []
|
143
142
|
end
|
144
143
|
inherit_on
|
@@ -169,7 +168,7 @@ module Nickel
|
|
169
168
|
elsif index_references_timespan(tindex)
|
170
169
|
return @constructs[tindex].start_time
|
171
170
|
else
|
172
|
-
|
171
|
+
fail 'ConstructInterpreter#start_time_from_tindex says: tindex does not reference a time or time span'
|
173
172
|
end
|
174
173
|
end
|
175
174
|
|
@@ -193,7 +192,6 @@ module Nickel
|
|
193
192
|
# One of this methods functions will be to assign proper am/pm values to time
|
194
193
|
# and timespan constructs if they were not specified.
|
195
194
|
def finalize_constructs
|
196
|
-
|
197
195
|
# First assign am/pm values to timespan constructs independent of
|
198
196
|
# other times in timemap.
|
199
197
|
finalize_timespan_constructs
|
@@ -205,7 +203,7 @@ module Nickel
|
|
205
203
|
# The time_indices array holds TimeConstruct and TimeSpanConstruct indices.
|
206
204
|
# The time_array will hold an array of ZTime objects to modify (potentially)
|
207
205
|
time_array = []
|
208
|
-
time_indices.each {|tindex| time_array << start_time_from_tindex(tindex)}
|
206
|
+
time_indices.each { |tindex| time_array << start_time_from_tindex(tindex) }
|
209
207
|
ZTime.am_pm_modifier(*time_array)
|
210
208
|
end
|
211
209
|
|
@@ -247,8 +245,8 @@ module Nickel
|
|
247
245
|
|
248
246
|
def occurrences_from_dates
|
249
247
|
@dci.each do |dindex|
|
250
|
-
occ_base = Occurrence.new(:
|
251
|
-
create_occurrence_for_each_time_in_time_map(occ_base, dindex) {|occ| @occurrences << occ}
|
248
|
+
occ_base = Occurrence.new(type: :single, start_date: @constructs[dindex].date)
|
249
|
+
create_occurrence_for_each_time_in_time_map(occ_base, dindex) { |occ| @occurrences << occ }
|
252
250
|
end
|
253
251
|
end
|
254
252
|
|
@@ -257,11 +255,11 @@ module Nickel
|
|
257
255
|
end
|
258
256
|
|
259
257
|
def occurrences_from_one_date_span
|
260
|
-
occ_base = Occurrence.new(:
|
261
|
-
:
|
262
|
-
:
|
263
|
-
:
|
264
|
-
create_occurrence_for_each_time_in_time_map(occ_base, @dsci[0]) {|occ| @occurrences << occ}
|
258
|
+
occ_base = Occurrence.new(type: :daily,
|
259
|
+
start_date: @constructs[@dsci[0]].start_date,
|
260
|
+
end_date: @constructs[@dsci[0]].end_date,
|
261
|
+
interval: 1)
|
262
|
+
create_occurrence_for_each_time_in_time_map(occ_base, @dsci[0]) { |occ| @occurrences << occ }
|
265
263
|
end
|
266
264
|
|
267
265
|
def found_recurrences_and_optional_date_span
|
@@ -271,7 +269,7 @@ module Nickel
|
|
271
269
|
def occurrences_from_recurrences_and_optional_date_span
|
272
270
|
if @dsci.size == 1
|
273
271
|
# If a date span exists, it functions as wrapper.
|
274
|
-
occ_base_opts = {:
|
272
|
+
occ_base_opts = { start_date: @constructs[@dsci[0]].start_date, end_date: @constructs[@dsci[0]].end_date }
|
275
273
|
else
|
276
274
|
# Perhaps there are type 0 or type 1 wrappers to provide start/end dates.
|
277
275
|
occ_base_opts = occ_base_opts_from_wrappers
|
@@ -284,7 +282,7 @@ module Nickel
|
|
284
282
|
# but they must be merged with start/end dates, if supplied.
|
285
283
|
occ_base = Occurrence.new(rec_occ_base_opts.merge(occ_base_opts))
|
286
284
|
# Attach times:
|
287
|
-
create_occurrence_for_each_time_in_time_map(occ_base, rcindex) {|occ| @occurrences << occ}
|
285
|
+
create_occurrence_for_each_time_in_time_map(occ_base, rcindex) { |occ| @occurrences << occ }
|
288
286
|
end
|
289
287
|
end
|
290
288
|
end
|
@@ -296,7 +294,7 @@ module Nickel
|
|
296
294
|
end
|
297
295
|
|
298
296
|
def occurrences_from_wrappers_only
|
299
|
-
occ_base = {:
|
297
|
+
occ_base = { type: :daily, interval: 1 }
|
300
298
|
@occurrences << Occurrence.new(occ_base.merge(occ_base_opts_from_wrappers))
|
301
299
|
end
|
302
300
|
|
@@ -319,22 +317,22 @@ module Nickel
|
|
319
317
|
if base_opts[:start_date].nil? && base_opts[:end_date].nil? # span must start today
|
320
318
|
base_opts[:start_date] = @curdate.dup
|
321
319
|
base_opts[:end_date] = case @constructs[wi].wrapper_type
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
320
|
+
when 2 then @curdate.add_days(@constructs[wi].wrapper_length)
|
321
|
+
when 3 then @curdate.add_weeks(@constructs[wi].wrapper_length)
|
322
|
+
when 4 then @curdate.add_months(@constructs[wi].wrapper_length)
|
323
|
+
end
|
326
324
|
elsif base_opts[:start_date] && base_opts[:end_date].nil?
|
327
325
|
base_opts[:end_date] = case @constructs[wi].wrapper_type
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
326
|
+
when 2 then base_opts[:start_date].add_days(@constructs[wi].wrapper_length)
|
327
|
+
when 3 then base_opts[:start_date].add_weeks(@constructs[wi].wrapper_length)
|
328
|
+
when 4 then base_opts[:start_date].add_months(@constructs[wi].wrapper_length)
|
329
|
+
end
|
332
330
|
elsif base_opts[:start_date].nil? && base_opts[:end_date] # for 6 months until jan 3rd
|
333
331
|
base_opts[:start_date] = case @constructs[wi].wrapper_type
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
332
|
+
when 2 then base_opts[:end_date].sub_days(@constructs[wi].wrapper_length)
|
333
|
+
when 3 then base_opts[:end_date].sub_weeks(@constructs[wi].wrapper_length)
|
334
|
+
when 4 then base_opts[:end_date].sub_months(@constructs[wi].wrapper_length)
|
335
|
+
end
|
338
336
|
end
|
339
337
|
end
|
340
338
|
end
|
data/lib/nickel/nlp.rb
CHANGED
@@ -6,16 +6,14 @@ require_relative 'construct_finder'
|
|
6
6
|
require_relative 'construct_interpreter'
|
7
7
|
|
8
8
|
module Nickel
|
9
|
-
|
10
9
|
class NLP
|
11
|
-
|
12
10
|
attr_reader :query, :input_date, :input_time, :nlp_query
|
13
11
|
attr_reader :construct_finder, :construct_interpreter
|
14
12
|
attr_reader :occurrences, :message
|
15
13
|
|
16
14
|
def initialize(query, date_time = Time.now)
|
17
|
-
|
18
|
-
str_time = date_time.strftime(
|
15
|
+
fail InvalidDateTimeError unless [DateTime, Time].include?(date_time.class)
|
16
|
+
str_time = date_time.strftime('%Y%m%dT%H%M%S')
|
19
17
|
validate_input query, str_time
|
20
18
|
@query = query.dup
|
21
19
|
@input_date = ZDate.new str_time[0..7] # up to T, note format is already verified
|
@@ -33,8 +31,8 @@ module Nickel
|
|
33
31
|
@construct_interpreter = ConstructInterpreter.new(@construct_finder.constructs, @input_date) # input_date only needed for wrappers
|
34
32
|
@construct_interpreter.run
|
35
33
|
|
36
|
-
@occurrences = @construct_interpreter.occurrences.each {|occ| occ.finalize(@input_date) } # finds start and end dates
|
37
|
-
@occurrences.
|
34
|
+
@occurrences = @construct_interpreter.occurrences.each { |occ| occ.finalize(@input_date) } # finds start and end dates
|
35
|
+
@occurrences.sort_by(&:start_date)
|
38
36
|
@occurrences
|
39
37
|
end
|
40
38
|
|
@@ -52,16 +50,16 @@ module Nickel
|
|
52
50
|
# now iterate through constructs, blow away any words between positions comp_start and comp_end
|
53
51
|
constructs.each do |c|
|
54
52
|
# create a range between comp_start and comp_end, iterate through it and wipe out words between them
|
55
|
-
(c.comp_start..c.comp_end).each {|x| message_array[x] = nil}
|
53
|
+
(c.comp_start..c.comp_end).each { |x| message_array[x] = nil }
|
56
54
|
# also wipe out words before comp start if it is something like in, at, on, or the
|
57
55
|
if c.comp_start - 1 >= 0 && message_array[c.comp_start - 1] =~ /\b(from|in|at|on|the|are|is|for)\b/
|
58
56
|
message_array[c.comp_start - 1] = nil
|
59
|
-
if
|
57
|
+
if Regexp.last_match(1) == 'the' && c.comp_start - 2 >= 0 && message_array[c.comp_start - 2] =~ /\b(for|on)\b/ # for the next three days; on the 27th;
|
60
58
|
message_array[c.comp_start - 2] = nil
|
61
|
-
if
|
59
|
+
if Regexp.last_match(1) == 'on' && c.comp_start - 3 >= 0 && message_array[c.comp_start - 3] =~ /\b(is|are)\b/ # is on the 28th; are on the 21st and 22nd;
|
62
60
|
message_array[c.comp_start - 3] = nil
|
63
61
|
end
|
64
|
-
elsif
|
62
|
+
elsif Regexp.last_match(1) == 'on' && c.comp_start - 2 >= 0 && message_array[c.comp_start - 2] =~ /\b(is|are)\b/ # is on tuesday; are on tuesday and wed;
|
65
63
|
message_array[c.comp_start - 2] = nil
|
66
64
|
end
|
67
65
|
end
|
@@ -70,40 +68,39 @@ module Nickel
|
|
70
68
|
# reloop and wipe out words after end of constructs, if they are followed by another construct
|
71
69
|
# note we already wiped out terms ahead of the constructs, so be sure to check for nil values, these indicate that a construct is followed by the nil
|
72
70
|
constructs.each_with_index do |c, i|
|
73
|
-
if message_array[c.comp_end+1] && message_array[c.comp_end + 1] ==
|
74
|
-
if message_array[c.comp_end + 2].nil? || (constructs[i+1] && constructs[i+1].comp_start == c.comp_end + 2)
|
71
|
+
if message_array[c.comp_end + 1] && message_array[c.comp_end + 1] == 'and' # do something tomorrow and on friday
|
72
|
+
if message_array[c.comp_end + 2].nil? || (constructs[i + 1] && constructs[i + 1].comp_start == c.comp_end + 2)
|
75
73
|
message_array[c.comp_end + 1] = nil
|
76
|
-
elsif message_array[c.comp_end + 2] ==
|
74
|
+
elsif message_array[c.comp_end + 2] == 'also' && message_array[c.comp_end + 3].nil? || (constructs[i + 1] && constructs[i + 1].comp_start == c.comp_end + 3) # do something tomorrow and also on friday
|
77
75
|
message_array[c.comp_end + 1] = nil
|
78
76
|
message_array[c.comp_end + 2] = nil
|
79
77
|
end
|
80
78
|
end
|
81
79
|
end
|
82
|
-
@message = message_array.compact.join(
|
80
|
+
@message = message_array.compact.join(' ') # remove nils and join the words with spaces
|
83
81
|
end
|
84
82
|
|
85
83
|
# returns any words in the query that appeared as input to their original case
|
86
84
|
def correct_case
|
87
85
|
orig = @query.split
|
88
86
|
latest = @message.split
|
89
|
-
orig.each_with_index do |original_word,j|
|
87
|
+
orig.each_with_index do |original_word, j|
|
90
88
|
if i = latest.index(original_word.downcase)
|
91
89
|
latest[i] = original_word
|
92
90
|
end
|
93
91
|
end
|
94
|
-
@message = latest.join(
|
92
|
+
@message = latest.join(' ')
|
95
93
|
end
|
96
94
|
|
97
|
-
def validate_input
|
98
|
-
|
99
|
-
|
95
|
+
def validate_input(query, date_time)
|
96
|
+
fail 'Empty NLP query' unless query.length > 0
|
97
|
+
fail 'NLP says: date_time is not in the correct format' unless date_time =~ /^\d{8}T\d{6}$/
|
100
98
|
end
|
101
99
|
end
|
102
100
|
|
103
101
|
class InvalidDateTimeError < StandardError
|
104
102
|
def message
|
105
|
-
|
103
|
+
'You must pass in a ruby DateTime or Time class object'
|
106
104
|
end
|
107
105
|
end
|
108
106
|
end
|
109
|
-
|
data/lib/nickel/nlp_query.rb
CHANGED
@@ -3,7 +3,6 @@ require_relative 'ztime'
|
|
3
3
|
require_relative 'nlp_query_constants'
|
4
4
|
|
5
5
|
module Nickel
|
6
|
-
|
7
6
|
class NLPQuery
|
8
7
|
include NLPQueryConstants
|
9
8
|
|
@@ -21,7 +20,7 @@ module Nickel
|
|
21
20
|
end
|
22
21
|
|
23
22
|
def query_formatting
|
24
|
-
query_str.gsub!(/\n/,'')
|
23
|
+
query_str.gsub!(/\n/, '')
|
25
24
|
query_str.downcase!
|
26
25
|
remove_unused_punctuation
|
27
26
|
replace_backslashes
|
@@ -54,14 +53,14 @@ module Nickel
|
|
54
53
|
if block_given?
|
55
54
|
# query_str.gsub!(args[0]) {yield(*m.to_a[1..-1])} # There is a bug here: If gsub matches more than once,
|
56
55
|
# then the first set of referenced matches will be passed to the block
|
57
|
-
ret_str = m.pre_match + m[0].sub(args[0]) {yield(*m.to_a[1..-1])} # this will take care of the first set of matches
|
56
|
+
ret_str = m.pre_match + m[0].sub(args[0]) { yield(*m.to_a[1..-1]) } # this will take care of the first set of matches
|
58
57
|
while (m_old = m.dup) && (m = m.post_match.match(args[0]))
|
59
|
-
ret_str << m.pre_match + m[0].sub(args[0]) {yield(*m.to_a[1..-1])}
|
58
|
+
ret_str << m.pre_match + m[0].sub(args[0]) { yield(*m.to_a[1..-1]) }
|
60
59
|
end
|
61
60
|
ret_str << m_old.post_match
|
62
|
-
query_str.sub!(/.*/,ret_str)
|
61
|
+
query_str.sub!(/.*/, ret_str)
|
63
62
|
else
|
64
|
-
query_str.gsub!(args[0],args[1])
|
63
|
+
query_str.gsub!(args[0], args[1])
|
65
64
|
end
|
66
65
|
end
|
67
66
|
end
|
@@ -71,338 +70,338 @@ module Nickel
|
|
71
70
|
end
|
72
71
|
|
73
72
|
def remove_unused_punctuation
|
74
|
-
nsub!(/,/,' ')
|
75
|
-
nsub!(/\./,'')
|
76
|
-
nsub!(/;/,'')
|
77
|
-
nsub!(/['`]/,'')
|
73
|
+
nsub!(/,/, ' ')
|
74
|
+
nsub!(/\./, '')
|
75
|
+
nsub!(/;/, '')
|
76
|
+
nsub!(/['`]/, '')
|
78
77
|
end
|
79
78
|
|
80
79
|
def replace_backslashes
|
81
|
-
nsub!(/\\/,'/')
|
80
|
+
nsub!(/\\/, '/')
|
82
81
|
end
|
83
82
|
|
84
83
|
def run_spell_check
|
85
|
-
nsub!(/tomm?orr?ow|romorrow/,'tomorrow')
|
86
|
-
nsub!(/weeknd/,'weekend')
|
87
|
-
nsub!(/weekends/,'every sat sun')
|
88
|
-
nsub!(/everyother/,'every other')
|
89
|
-
nsub!(/weak/,'week')
|
90
|
-
nsub!(/everyweek/,'every week')
|
91
|
-
nsub!(/everymonth/,'every month')
|
92
|
-
nsub!(/c?h[oa]nn?[aui][ck][ck]?[ua]h?/,'hannukkah')
|
93
|
-
nsub!(/frist/,'1st')
|
94
|
-
nsub!(/eveyr|evrey/,'every')
|
95
|
-
nsub!(/fridya|friady|fridy/,'friday')
|
96
|
-
nsub!(/thurdsday/,'thursday')
|
97
|
-
nsub!(/x-?mas/,'christmas')
|
98
|
-
nsub!(/st\s+(patrick|patty|pat)s?(\s+day)?/,'st patricks day')
|
99
|
-
nsub!(/frouth/,'fourth')
|
100
|
-
nsub!(/\btill\b/,'through')
|
101
|
-
nsub!(/\bthru\b|\bthrouh\b|\bthough\b|\bthrew\b|\bthrow\b|\bthroug\b|\bthuogh\b/,'through')
|
102
|
-
nsub!(/weekdays|every\s+weekday/,'every monday through friday')
|
103
|
-
nsub!(/\bevery?day\b/,'every day')
|
104
|
-
nsub!(/eigth/,'eighth')
|
105
|
-
nsub!(/bi[-\s]monthly/,'bimonthly')
|
106
|
-
nsub!(/tri[-\s]monthly/,'trimonthly')
|
84
|
+
nsub!(/tomm?orr?ow|romorrow/, 'tomorrow')
|
85
|
+
nsub!(/weeknd/, 'weekend')
|
86
|
+
nsub!(/weekends/, 'every sat sun')
|
87
|
+
nsub!(/everyother/, 'every other')
|
88
|
+
nsub!(/weak/, 'week')
|
89
|
+
nsub!(/everyweek/, 'every week')
|
90
|
+
nsub!(/everymonth/, 'every month')
|
91
|
+
nsub!(/c?h[oa]nn?[aui][ck][ck]?[ua]h?/, 'hannukkah')
|
92
|
+
nsub!(/frist/, '1st')
|
93
|
+
nsub!(/eveyr|evrey/, 'every')
|
94
|
+
nsub!(/fridya|friady|fridy/, 'friday')
|
95
|
+
nsub!(/thurdsday/, 'thursday')
|
96
|
+
nsub!(/x-?mas/, 'christmas')
|
97
|
+
nsub!(/st\s+(patrick|patty|pat)s?(\s+day)?/, 'st patricks day')
|
98
|
+
nsub!(/frouth/, 'fourth')
|
99
|
+
nsub!(/\btill\b/, 'through')
|
100
|
+
nsub!(/\bthru\b|\bthrouh\b|\bthough\b|\bthrew\b|\bthrow\b|\bthroug\b|\bthuogh\b/, 'through')
|
101
|
+
nsub!(/weekdays|every\s+weekday/, 'every monday through friday')
|
102
|
+
nsub!(/\bevery?day\b/, 'every day')
|
103
|
+
nsub!(/eigth/, 'eighth')
|
104
|
+
nsub!(/bi[-\s]monthly/, 'bimonthly')
|
105
|
+
nsub!(/tri[-\s]monthly/, 'trimonthly')
|
107
106
|
end
|
108
107
|
|
109
108
|
def remove_unnecessary_words
|
110
|
-
nsub!(/coming/,'')
|
111
|
-
nsub!(/o'?clock/,'')
|
112
|
-
nsub!(/\btom\b/,'tomorrow')
|
113
|
-
nsub!(/\s*in\s+(the\s+)?(morning|am)/,' am')
|
114
|
-
nsub!(/\s*in\s+(the\s+)?(afternoon|pm|evenn?ing)/,' pm')
|
115
|
-
nsub!(/\s*at\s+night/,'pm')
|
116
|
-
nsub!(/(after\s*)?noon(ish)?/,'12:00pm')
|
117
|
-
nsub!(/\bmi(dn|nd)ight\b/,'12:00am')
|
118
|
-
nsub!(/final/,'last')
|
119
|
-
nsub!(/recur(s|r?ing)?/,'repeats')
|
120
|
-
nsub!(/\beach\b/,'every')
|
121
|
-
nsub!(/running\s+(until|through)/,'through')
|
122
|
-
nsub!(/runn?(s|ing)|go(ing|e?s)/,'for')
|
123
|
-
nsub!(/next\s+occ?urr?[ae]nce(\s+is)?/,'start')
|
124
|
-
nsub!(/next\s+date(\s+it)?(\s+occ?urr?s)?(\s+is)?/,'start')
|
125
|
-
nsub!(/forever/,'repeats daily')
|
126
|
-
nsub!(/\bany(?:\s*)day\b/,'every day')
|
127
|
-
nsub!(/^anytime$/,'every day') # user entered anytime by itself, not 'dayname anytime', caught next
|
128
|
-
nsub!(/any(\s)?time|whenever/,'all day')
|
109
|
+
nsub!(/coming/, '')
|
110
|
+
nsub!(/o'?clock/, '')
|
111
|
+
nsub!(/\btom\b/, 'tomorrow')
|
112
|
+
nsub!(/\s*in\s+(the\s+)?(morning|am)/, ' am')
|
113
|
+
nsub!(/\s*in\s+(the\s+)?(afternoon|pm|evenn?ing)/, ' pm')
|
114
|
+
nsub!(/\s*at\s+night/, 'pm')
|
115
|
+
nsub!(/(after\s*)?noon(ish)?/, '12:00pm')
|
116
|
+
nsub!(/\bmi(dn|nd)ight\b/, '12:00am')
|
117
|
+
nsub!(/final/, 'last')
|
118
|
+
nsub!(/recur(s|r?ing)?/, 'repeats')
|
119
|
+
nsub!(/\beach\b/, 'every')
|
120
|
+
nsub!(/running\s+(until|through)/, 'through')
|
121
|
+
nsub!(/runn?(s|ing)|go(ing|e?s)/, 'for')
|
122
|
+
nsub!(/next\s+occ?urr?[ae]nce(\s+is)?/, 'start')
|
123
|
+
nsub!(/next\s+date(\s+it)?(\s+occ?urr?s)?(\s+is)?/, 'start')
|
124
|
+
nsub!(/forever/, 'repeats daily')
|
125
|
+
nsub!(/\bany(?:\s*)day\b/, 'every day')
|
126
|
+
nsub!(/^anytime$/, 'every day') # user entered anytime by itself, not 'dayname anytime', caught next
|
127
|
+
nsub!(/any(\s)?time|whenever/, 'all day')
|
129
128
|
end
|
130
129
|
|
131
130
|
def standardize_days
|
132
|
-
nsub!(/mondays/,'every mon')
|
133
|
-
nsub!(/monday/,'mon')
|
134
|
-
nsub!(/tuesdays/,'every tue')
|
135
|
-
nsub!(/tuesadys/,'every tue')
|
136
|
-
nsub!(/tuesday/,'tue')
|
137
|
-
nsub!(/tuesady/,'tue')
|
138
|
-
nsub!(/wednesdays/,'every wed')
|
139
|
-
nsub!(/wednesday/,'wed')
|
140
|
-
nsub!(/thursdays/,'every thu')
|
141
|
-
nsub!(/thurdsays/,'every thu')
|
142
|
-
nsub!(/thursadys/,'every thu')
|
143
|
-
nsub!(/thursday/,'thu')
|
144
|
-
nsub!(/thurdsay/,'thu')
|
145
|
-
nsub!(/thursady/,'thu')
|
146
|
-
nsub!(/\bthurd?\b/,'thu')
|
147
|
-
nsub!(/\bthurs?d?\b/,'thu')
|
148
|
-
nsub!(/fridays/,'every fri')
|
149
|
-
nsub!(/firdays/,'every fri')
|
150
|
-
nsub!(/friday/,'fri')
|
151
|
-
nsub!(/firday/,'fri')
|
152
|
-
nsub!(/saturdays/,'every sat')
|
153
|
-
nsub!(/saturday/,'sat')
|
154
|
-
nsub!(/sundays/,'every sun')
|
155
|
-
nsub!(/sunday/,'sun')
|
131
|
+
nsub!(/mondays/, 'every mon')
|
132
|
+
nsub!(/monday/, 'mon')
|
133
|
+
nsub!(/tuesdays/, 'every tue')
|
134
|
+
nsub!(/tuesadys/, 'every tue')
|
135
|
+
nsub!(/tuesday/, 'tue')
|
136
|
+
nsub!(/tuesady/, 'tue')
|
137
|
+
nsub!(/wednesdays/, 'every wed')
|
138
|
+
nsub!(/wednesday/, 'wed')
|
139
|
+
nsub!(/thursdays/, 'every thu')
|
140
|
+
nsub!(/thurdsays/, 'every thu')
|
141
|
+
nsub!(/thursadys/, 'every thu')
|
142
|
+
nsub!(/thursday/, 'thu')
|
143
|
+
nsub!(/thurdsay/, 'thu')
|
144
|
+
nsub!(/thursady/, 'thu')
|
145
|
+
nsub!(/\bthurd?\b/, 'thu')
|
146
|
+
nsub!(/\bthurs?d?\b/, 'thu')
|
147
|
+
nsub!(/fridays/, 'every fri')
|
148
|
+
nsub!(/firdays/, 'every fri')
|
149
|
+
nsub!(/friday/, 'fri')
|
150
|
+
nsub!(/firday/, 'fri')
|
151
|
+
nsub!(/saturdays/, 'every sat')
|
152
|
+
nsub!(/saturday/, 'sat')
|
153
|
+
nsub!(/sundays/, 'every sun')
|
154
|
+
nsub!(/sunday/, 'sun')
|
156
155
|
end
|
157
156
|
|
158
157
|
def standardize_months
|
159
|
-
nsub!(/january/,'jan')
|
160
|
-
nsub!(/february/,'feb')
|
158
|
+
nsub!(/january/, 'jan')
|
159
|
+
nsub!(/february/, 'feb')
|
161
160
|
nsub!(/febr/, 'feb')
|
162
|
-
nsub!(/march/,'mar')
|
163
|
-
nsub!(/april/,'apr')
|
164
|
-
nsub!(/may/,'may')
|
165
|
-
nsub!(/june/,'jun')
|
166
|
-
nsub!(/july/,'jul')
|
167
|
-
nsub!(/august/,'aug')
|
168
|
-
nsub!(/september/,'sep')
|
169
|
-
nsub!(/sept/,'sep')
|
170
|
-
nsub!(/october/,'oct')
|
171
|
-
nsub!(/november/,'nov')
|
172
|
-
nsub!(/novermber/,'nov')
|
173
|
-
nsub!(/novem/,'nov')
|
174
|
-
nsub!(/decemb?e?r?/,'dec')
|
161
|
+
nsub!(/march/, 'mar')
|
162
|
+
nsub!(/april/, 'apr')
|
163
|
+
nsub!(/may/, 'may')
|
164
|
+
nsub!(/june/, 'jun')
|
165
|
+
nsub!(/july/, 'jul')
|
166
|
+
nsub!(/august/, 'aug')
|
167
|
+
nsub!(/september/, 'sep')
|
168
|
+
nsub!(/sept/, 'sep')
|
169
|
+
nsub!(/october/, 'oct')
|
170
|
+
nsub!(/november/, 'nov')
|
171
|
+
nsub!(/novermber/, 'nov')
|
172
|
+
nsub!(/novem/, 'nov')
|
173
|
+
nsub!(/decemb?e?r?/, 'dec')
|
175
174
|
end
|
176
175
|
|
177
176
|
def standardize_numbers
|
178
|
-
nsub!(/\bone\s*-?\s*hundred\b/,'100')
|
179
|
-
nsub!(/\bone\s*-?\s*hundredth\b/,'100th')
|
180
|
-
nsub!(/\bninety\s*-?\s*nine\b/,'99')
|
181
|
-
nsub!(/\bninety\s*-?\s*ninth\b/,'99th')
|
182
|
-
nsub!(/\bninety\s*-?\s*eight\b/,'98')
|
183
|
-
nsub!(/\bninety\s*-?\s*eighth\b/,'98th')
|
184
|
-
nsub!(/\bninety\s*-?\s*seven\b/,'97')
|
185
|
-
nsub!(/\bninety\s*-?\s*seventh\b/,'97th')
|
186
|
-
nsub!(/\bninety\s*-?\s*six\b/,'96')
|
187
|
-
nsub!(/\bninety\s*-?\s*sixth\b/,'96th')
|
188
|
-
nsub!(/\bninety\s*-?\s*five\b/,'95')
|
189
|
-
nsub!(/\bninety\s*-?\s*fifth\b/,'95th')
|
190
|
-
nsub!(/\bninety\s*-?\s*four\b/,'94')
|
191
|
-
nsub!(/\bninety\s*-?\s*fourth\b/,'94th')
|
192
|
-
nsub!(/\bninety\s*-?\s*three\b/,'93')
|
193
|
-
nsub!(/\bninety\s*-?\s*third\b/,'93rd')
|
194
|
-
nsub!(/\bninety\s*-?\s*two\b/,'92')
|
195
|
-
nsub!(/\bninety\s*-?\s*second\b/,'92nd')
|
196
|
-
nsub!(/\bninety\s*-?\s*one\b/,'91')
|
197
|
-
nsub!(/\bninety\s*-?\s*first\b/,'91st')
|
198
|
-
nsub!(/\bninety\b/,'90')
|
199
|
-
nsub!(/\bninetieth\b/,'90th')
|
200
|
-
nsub!(/\beighty\s*-?\s*nine\b/,'89')
|
201
|
-
nsub!(/\beighty\s*-?\s*ninth\b/,'89th')
|
202
|
-
nsub!(/\beighty\s*-?\s*eight\b/,'88')
|
203
|
-
nsub!(/\beighty\s*-?\s*eighth\b/,'88th')
|
204
|
-
nsub!(/\beighty\s*-?\s*seven\b/,'87')
|
205
|
-
nsub!(/\beighty\s*-?\s*seventh\b/,'87th')
|
206
|
-
nsub!(/\beighty\s*-?\s*six\b/,'86')
|
207
|
-
nsub!(/\beighty\s*-?\s*sixth\b/,'86th')
|
208
|
-
nsub!(/\beighty\s*-?\s*five\b/,'85')
|
209
|
-
nsub!(/\beighty\s*-?\s*fifth\b/,'85th')
|
210
|
-
nsub!(/\beighty\s*-?\s*four\b/,'84')
|
211
|
-
nsub!(/\beighty\s*-?\s*fourth\b/,'84th')
|
212
|
-
nsub!(/\beighty\s*-?\s*three\b/,'83')
|
213
|
-
nsub!(/\beighty\s*-?\s*third\b/,'83rd')
|
214
|
-
nsub!(/\beighty\s*-?\s*two\b/,'82')
|
215
|
-
nsub!(/\beighty\s*-?\s*second\b/,'82nd')
|
216
|
-
nsub!(/\beighty\s*-?\s*one\b/,'81')
|
217
|
-
nsub!(/\beighty\s*-?\s*first\b/,'81st')
|
218
|
-
nsub!(/\beighty\b/,'80')
|
219
|
-
nsub!(/\beightieth\b/,'80th')
|
220
|
-
nsub!(/\bseventy\s*-?\s*nine\b/,'79')
|
221
|
-
nsub!(/\bseventy\s*-?\s*ninth\b/,'79th')
|
222
|
-
nsub!(/\bseventy\s*-?\s*eight\b/,'78')
|
223
|
-
nsub!(/\bseventy\s*-?\s*eighth\b/,'78th')
|
224
|
-
nsub!(/\bseventy\s*-?\s*seven\b/,'77')
|
225
|
-
nsub!(/\bseventy\s*-?\s*seventh\b/,'77th')
|
226
|
-
nsub!(/\bseventy\s*-?\s*six\b/,'76')
|
227
|
-
nsub!(/\bseventy\s*-?\s*sixth\b/,'76th')
|
228
|
-
nsub!(/\bseventy\s*-?\s*five\b/,'75')
|
229
|
-
nsub!(/\bseventy\s*-?\s*fifth\b/,'75th')
|
230
|
-
nsub!(/\bseventy\s*-?\s*four\b/,'74')
|
231
|
-
nsub!(/\bseventy\s*-?\s*fourth\b/,'74th')
|
232
|
-
nsub!(/\bseventy\s*-?\s*three\b/,'73')
|
233
|
-
nsub!(/\bseventy\s*-?\s*third\b/,'73rd')
|
234
|
-
nsub!(/\bseventy\s*-?\s*two\b/,'72')
|
235
|
-
nsub!(/\bseventy\s*-?\s*second\b/,'72nd')
|
236
|
-
nsub!(/\bseventy\s*-?\s*one\b/,'71')
|
237
|
-
nsub!(/\bseventy\s*-?\s*first\b/,'71st')
|
238
|
-
nsub!(/\bseventy\b/,'70')
|
239
|
-
nsub!(/\bseventieth\b/,'70th')
|
240
|
-
nsub!(/\bsixty\s*-?\s*nine\b/,'69')
|
241
|
-
nsub!(/\bsixty\s*-?\s*ninth\b/,'69th')
|
242
|
-
nsub!(/\bsixty\s*-?\s*eight\b/,'68')
|
243
|
-
nsub!(/\bsixty\s*-?\s*eighth\b/,'68th')
|
244
|
-
nsub!(/\bsixty\s*-?\s*seven\b/,'67')
|
245
|
-
nsub!(/\bsixty\s*-?\s*seventh\b/,'67th')
|
246
|
-
nsub!(/\bsixty\s*-?\s*six\b/,'66')
|
247
|
-
nsub!(/\bsixty\s*-?\s*sixth\b/,'66th')
|
248
|
-
nsub!(/\bsixty\s*-?\s*five\b/,'65')
|
249
|
-
nsub!(/\bsixty\s*-?\s*fifth\b/,'65th')
|
250
|
-
nsub!(/\bsixty\s*-?\s*four\b/,'64')
|
251
|
-
nsub!(/\bsixty\s*-?\s*fourth\b/,'64th')
|
252
|
-
nsub!(/\bsixty\s*-?\s*three\b/,'63')
|
253
|
-
nsub!(/\bsixty\s*-?\s*third\b/,'63rd')
|
254
|
-
nsub!(/\bsixty\s*-?\s*two\b/,'62')
|
255
|
-
nsub!(/\bsixty\s*-?\s*second\b/,'62nd')
|
256
|
-
nsub!(/\bsixty\s*-?\s*one\b/,'61')
|
257
|
-
nsub!(/\bsixty\s*-?\s*first\b/,'61st')
|
258
|
-
nsub!(/\bsixty\b/,'60')
|
259
|
-
nsub!(/\bsixtieth\b/,'60th')
|
260
|
-
nsub!(/\bfifty\s*-?\s*nine\b/,'59')
|
261
|
-
nsub!(/\bfifty\s*-?\s*ninth\b/,'59th')
|
262
|
-
nsub!(/\bfifty\s*-?\s*eight\b/,'58')
|
263
|
-
nsub!(/\bfifty\s*-?\s*eighth\b/,'58th')
|
264
|
-
nsub!(/\bfifty\s*-?\s*seven\b/,'57')
|
265
|
-
nsub!(/\bfifty\s*-?\s*seventh\b/,'57th')
|
266
|
-
nsub!(/\bfifty\s*-?\s*six\b/,'56')
|
267
|
-
nsub!(/\bfifty\s*-?\s*sixth\b/,'56th')
|
268
|
-
nsub!(/\bfifty\s*-?\s*five\b/,'55')
|
269
|
-
nsub!(/\bfifty\s*-?\s*fifth\b/,'55th')
|
270
|
-
nsub!(/\bfifty\s*-?\s*four\b/,'54')
|
271
|
-
nsub!(/\bfifty\s*-?\s*fourth\b/,'54th')
|
272
|
-
nsub!(/\bfifty\s*-?\s*three\b/,'53')
|
273
|
-
nsub!(/\bfifty\s*-?\s*third\b/,'53rd')
|
274
|
-
nsub!(/\bfifty\s*-?\s*two\b/,'52')
|
275
|
-
nsub!(/\bfifty\s*-?\s*second\b/,'52nd')
|
276
|
-
nsub!(/\bfifty\s*-?\s*one\b/,'51')
|
277
|
-
nsub!(/\bfifty\s*-?\s*first\b/,'51st')
|
278
|
-
nsub!(/\bfifty\b/,'50')
|
279
|
-
nsub!(/\bfiftieth\b/,'50th')
|
280
|
-
nsub!(/\bfourty\s*-?\s*nine\b/,'49')
|
281
|
-
nsub!(/\bfourty\s*-?\s*ninth\b/,'49th')
|
282
|
-
nsub!(/\bfourty\s*-?\s*eight\b/,'48')
|
283
|
-
nsub!(/\bfourty\s*-?\s*eighth\b/,'48th')
|
284
|
-
nsub!(/\bfourty\s*-?\s*seven\b/,'47')
|
285
|
-
nsub!(/\bfourty\s*-?\s*seventh\b/,'47th')
|
286
|
-
nsub!(/\bfourty\s*-?\s*six\b/,'46')
|
287
|
-
nsub!(/\bfourty\s*-?\s*sixth\b/,'46th')
|
288
|
-
nsub!(/\bfourty\s*-?\s*five\b/,'45')
|
289
|
-
nsub!(/\bfourty\s*-?\s*fifth\b/,'45th')
|
290
|
-
nsub!(/\bfourty\s*-?\s*four\b/,'44')
|
291
|
-
nsub!(/\bfourty\s*-?\s*fourth\b/,'44th')
|
292
|
-
nsub!(/\bfourty\s*-?\s*three\b/,'43')
|
293
|
-
nsub!(/\bfourty\s*-?\s*third\b/,'43rd')
|
294
|
-
nsub!(/\bfourty\s*-?\s*two\b/,'42')
|
295
|
-
nsub!(/\bfourty\s*-?\s*second\b/,'42nd')
|
296
|
-
nsub!(/\bfourty\s*-?\s*one\b/,'41')
|
297
|
-
nsub!(/\bfourty\s*-?\s*first\b/,'41st')
|
298
|
-
nsub!(/\bfourty\b/,'40')
|
299
|
-
nsub!(/\bfourtieth\b/,'40th')
|
300
|
-
nsub!(/\bthirty\s*-?\s*nine\b/,'39')
|
301
|
-
nsub!(/\bthirty\s*-?\s*ninth\b/,'39th')
|
302
|
-
nsub!(/\bthirty\s*-?\s*eight\b/,'38')
|
303
|
-
nsub!(/\bthirty\s*-?\s*eighth\b/,'38th')
|
304
|
-
nsub!(/\bthirty\s*-?\s*seven\b/,'37')
|
305
|
-
nsub!(/\bthirty\s*-?\s*seventh\b/,'37th')
|
306
|
-
nsub!(/\bthirty\s*-?\s*six\b/,'36')
|
307
|
-
nsub!(/\bthirty\s*-?\s*sixth\b/,'36th')
|
308
|
-
nsub!(/\bthirty\s*-?\s*five\b/,'35')
|
309
|
-
nsub!(/\bthirty\s*-?\s*fifth\b/,'35th')
|
310
|
-
nsub!(/\bthirty\s*-?\s*four\b/,'34')
|
311
|
-
nsub!(/\bthirty\s*-?\s*fourth\b/,'34th')
|
312
|
-
nsub!(/\bthirty\s*-?\s*three\b/,'33')
|
313
|
-
nsub!(/\bthirty\s*-?\s*third\b/,'33rd')
|
314
|
-
nsub!(/\bthirty\s*-?\s*two\b/,'32')
|
315
|
-
nsub!(/\bthirty\s*-?\s*second\b/,'32nd')
|
316
|
-
nsub!(/\bthirty\s*-?\s*one\b/,'31')
|
317
|
-
nsub!(/\bthirty\s*-?\s*first\b/,'31st')
|
318
|
-
nsub!(/\bthirty\b/,'30')
|
319
|
-
nsub!(/\bthirtieth\b/,'30th')
|
320
|
-
nsub!(/\btwenty\s*-?\s*nine\b/,'29')
|
321
|
-
nsub!(/\btwenty\s*-?\s*ninth\b/,'29th')
|
322
|
-
nsub!(/\btwenty\s*-?\s*eight\b/,'28')
|
323
|
-
nsub!(/\btwenty\s*-?\s*eighth\b/,'28th')
|
324
|
-
nsub!(/\btwenty\s*-?\s*seven\b/,'27')
|
325
|
-
nsub!(/\btwenty\s*-?\s*seventh\b/,'27th')
|
326
|
-
nsub!(/\btwenty\s*-?\s*six\b/,'26')
|
327
|
-
nsub!(/\btwenty\s*-?\s*sixth\b/,'26th')
|
328
|
-
nsub!(/\btwenty\s*-?\s*five\b/,'25')
|
329
|
-
nsub!(/\btwenty\s*-?\s*fifth\b/,'25th')
|
330
|
-
nsub!(/\btwenty\s*-?\s*four\b/,'24')
|
331
|
-
nsub!(/\btwenty\s*-?\s*fourth\b/,'24th')
|
332
|
-
nsub!(/\btwenty\s*-?\s*three\b/,'23')
|
333
|
-
nsub!(/\btwenty\s*-?\s*third\b/,'23rd')
|
334
|
-
nsub!(/\btwenty\s*-?\s*two\b/,'22')
|
335
|
-
nsub!(/\btwenty\s*-?\s*second\b/,'22nd')
|
336
|
-
nsub!(/\btwenty\s*-?\s*one\b/,'21')
|
337
|
-
nsub!(/\btwenty\s*-?\s*first\b/,'21st')
|
338
|
-
nsub!(/\btwenty\b/,'20')
|
339
|
-
nsub!(/\btwentieth\b/,'20th')
|
340
|
-
nsub!(/\bnineteen\b/,'19')
|
341
|
-
nsub!(/\bnineteenth\b/,'19th')
|
342
|
-
nsub!(/\beighteen\b/,'18')
|
343
|
-
nsub!(/\beighteenth\b/,'18th')
|
344
|
-
nsub!(/\bseventeen\b/,'17')
|
345
|
-
nsub!(/\bseventeenth\b/,'17th')
|
346
|
-
nsub!(/\bsixteen\b/,'16')
|
347
|
-
nsub!(/\bsixteenth\b/,'16th')
|
348
|
-
nsub!(/\bfifteen\b/,'15')
|
349
|
-
nsub!(/\bfifteenth\b/,'15th')
|
350
|
-
nsub!(/\bfourteen\b/,'14')
|
351
|
-
nsub!(/\bfourteenth\b/,'14th')
|
352
|
-
nsub!(/\bthirteen/,'13')
|
353
|
-
nsub!(/\bthirteenth/,'13th')
|
354
|
-
nsub!(/\btwelve\b/,'12')
|
355
|
-
nsub!(/\btwelfth\b/,'12th')
|
356
|
-
nsub!(/\beleven\b/,'11')
|
357
|
-
nsub!(/\beleventh\b/,'11th')
|
358
|
-
nsub!(/\bten\b/,'10')
|
359
|
-
nsub!(/\btenth\b/,'10th')
|
360
|
-
nsub!(/\bnine\b/,'9')
|
361
|
-
nsub!(/\bninth\b/,'9th')
|
362
|
-
nsub!(/\beight\b/,'8')
|
363
|
-
nsub!(/\beighth\b/,'8th')
|
364
|
-
nsub!(/\bseven\b/,'7')
|
365
|
-
nsub!(/\bseventh\b/,'7th')
|
366
|
-
nsub!(/\bsix\b/,'6')
|
367
|
-
nsub!(/\bsixth\b/,'6th')
|
368
|
-
nsub!(/\bfive\b/,'5')
|
369
|
-
nsub!(/\bfifth\b/,'5th')
|
370
|
-
nsub!(/\bfour\b/,'4')
|
371
|
-
nsub!(/\bfourth\b/,'4th')
|
372
|
-
nsub!(/\bthree\b/,'3')
|
373
|
-
nsub!(/\bthird\b/,'3rd')
|
374
|
-
nsub!(/\btwo\b/,'2')
|
375
|
-
nsub!(/\bsecond\b/,'2nd')
|
376
|
-
nsub!(/\bone\b/,'1')
|
377
|
-
nsub!(/\bfirst\b/,'1st')
|
378
|
-
nsub!(/\bzero\b/,'0')
|
379
|
-
nsub!(/\bzeroth\b/,'0th')
|
177
|
+
nsub!(/\bone\s*-?\s*hundred\b/, '100')
|
178
|
+
nsub!(/\bone\s*-?\s*hundredth\b/, '100th')
|
179
|
+
nsub!(/\bninety\s*-?\s*nine\b/, '99')
|
180
|
+
nsub!(/\bninety\s*-?\s*ninth\b/, '99th')
|
181
|
+
nsub!(/\bninety\s*-?\s*eight\b/, '98')
|
182
|
+
nsub!(/\bninety\s*-?\s*eighth\b/, '98th')
|
183
|
+
nsub!(/\bninety\s*-?\s*seven\b/, '97')
|
184
|
+
nsub!(/\bninety\s*-?\s*seventh\b/, '97th')
|
185
|
+
nsub!(/\bninety\s*-?\s*six\b/, '96')
|
186
|
+
nsub!(/\bninety\s*-?\s*sixth\b/, '96th')
|
187
|
+
nsub!(/\bninety\s*-?\s*five\b/, '95')
|
188
|
+
nsub!(/\bninety\s*-?\s*fifth\b/, '95th')
|
189
|
+
nsub!(/\bninety\s*-?\s*four\b/, '94')
|
190
|
+
nsub!(/\bninety\s*-?\s*fourth\b/, '94th')
|
191
|
+
nsub!(/\bninety\s*-?\s*three\b/, '93')
|
192
|
+
nsub!(/\bninety\s*-?\s*third\b/, '93rd')
|
193
|
+
nsub!(/\bninety\s*-?\s*two\b/, '92')
|
194
|
+
nsub!(/\bninety\s*-?\s*second\b/, '92nd')
|
195
|
+
nsub!(/\bninety\s*-?\s*one\b/, '91')
|
196
|
+
nsub!(/\bninety\s*-?\s*first\b/, '91st')
|
197
|
+
nsub!(/\bninety\b/, '90')
|
198
|
+
nsub!(/\bninetieth\b/, '90th')
|
199
|
+
nsub!(/\beighty\s*-?\s*nine\b/, '89')
|
200
|
+
nsub!(/\beighty\s*-?\s*ninth\b/, '89th')
|
201
|
+
nsub!(/\beighty\s*-?\s*eight\b/, '88')
|
202
|
+
nsub!(/\beighty\s*-?\s*eighth\b/, '88th')
|
203
|
+
nsub!(/\beighty\s*-?\s*seven\b/, '87')
|
204
|
+
nsub!(/\beighty\s*-?\s*seventh\b/, '87th')
|
205
|
+
nsub!(/\beighty\s*-?\s*six\b/, '86')
|
206
|
+
nsub!(/\beighty\s*-?\s*sixth\b/, '86th')
|
207
|
+
nsub!(/\beighty\s*-?\s*five\b/, '85')
|
208
|
+
nsub!(/\beighty\s*-?\s*fifth\b/, '85th')
|
209
|
+
nsub!(/\beighty\s*-?\s*four\b/, '84')
|
210
|
+
nsub!(/\beighty\s*-?\s*fourth\b/, '84th')
|
211
|
+
nsub!(/\beighty\s*-?\s*three\b/, '83')
|
212
|
+
nsub!(/\beighty\s*-?\s*third\b/, '83rd')
|
213
|
+
nsub!(/\beighty\s*-?\s*two\b/, '82')
|
214
|
+
nsub!(/\beighty\s*-?\s*second\b/, '82nd')
|
215
|
+
nsub!(/\beighty\s*-?\s*one\b/, '81')
|
216
|
+
nsub!(/\beighty\s*-?\s*first\b/, '81st')
|
217
|
+
nsub!(/\beighty\b/, '80')
|
218
|
+
nsub!(/\beightieth\b/, '80th')
|
219
|
+
nsub!(/\bseventy\s*-?\s*nine\b/, '79')
|
220
|
+
nsub!(/\bseventy\s*-?\s*ninth\b/, '79th')
|
221
|
+
nsub!(/\bseventy\s*-?\s*eight\b/, '78')
|
222
|
+
nsub!(/\bseventy\s*-?\s*eighth\b/, '78th')
|
223
|
+
nsub!(/\bseventy\s*-?\s*seven\b/, '77')
|
224
|
+
nsub!(/\bseventy\s*-?\s*seventh\b/, '77th')
|
225
|
+
nsub!(/\bseventy\s*-?\s*six\b/, '76')
|
226
|
+
nsub!(/\bseventy\s*-?\s*sixth\b/, '76th')
|
227
|
+
nsub!(/\bseventy\s*-?\s*five\b/, '75')
|
228
|
+
nsub!(/\bseventy\s*-?\s*fifth\b/, '75th')
|
229
|
+
nsub!(/\bseventy\s*-?\s*four\b/, '74')
|
230
|
+
nsub!(/\bseventy\s*-?\s*fourth\b/, '74th')
|
231
|
+
nsub!(/\bseventy\s*-?\s*three\b/, '73')
|
232
|
+
nsub!(/\bseventy\s*-?\s*third\b/, '73rd')
|
233
|
+
nsub!(/\bseventy\s*-?\s*two\b/, '72')
|
234
|
+
nsub!(/\bseventy\s*-?\s*second\b/, '72nd')
|
235
|
+
nsub!(/\bseventy\s*-?\s*one\b/, '71')
|
236
|
+
nsub!(/\bseventy\s*-?\s*first\b/, '71st')
|
237
|
+
nsub!(/\bseventy\b/, '70')
|
238
|
+
nsub!(/\bseventieth\b/, '70th')
|
239
|
+
nsub!(/\bsixty\s*-?\s*nine\b/, '69')
|
240
|
+
nsub!(/\bsixty\s*-?\s*ninth\b/, '69th')
|
241
|
+
nsub!(/\bsixty\s*-?\s*eight\b/, '68')
|
242
|
+
nsub!(/\bsixty\s*-?\s*eighth\b/, '68th')
|
243
|
+
nsub!(/\bsixty\s*-?\s*seven\b/, '67')
|
244
|
+
nsub!(/\bsixty\s*-?\s*seventh\b/, '67th')
|
245
|
+
nsub!(/\bsixty\s*-?\s*six\b/, '66')
|
246
|
+
nsub!(/\bsixty\s*-?\s*sixth\b/, '66th')
|
247
|
+
nsub!(/\bsixty\s*-?\s*five\b/, '65')
|
248
|
+
nsub!(/\bsixty\s*-?\s*fifth\b/, '65th')
|
249
|
+
nsub!(/\bsixty\s*-?\s*four\b/, '64')
|
250
|
+
nsub!(/\bsixty\s*-?\s*fourth\b/, '64th')
|
251
|
+
nsub!(/\bsixty\s*-?\s*three\b/, '63')
|
252
|
+
nsub!(/\bsixty\s*-?\s*third\b/, '63rd')
|
253
|
+
nsub!(/\bsixty\s*-?\s*two\b/, '62')
|
254
|
+
nsub!(/\bsixty\s*-?\s*second\b/, '62nd')
|
255
|
+
nsub!(/\bsixty\s*-?\s*one\b/, '61')
|
256
|
+
nsub!(/\bsixty\s*-?\s*first\b/, '61st')
|
257
|
+
nsub!(/\bsixty\b/, '60')
|
258
|
+
nsub!(/\bsixtieth\b/, '60th')
|
259
|
+
nsub!(/\bfifty\s*-?\s*nine\b/, '59')
|
260
|
+
nsub!(/\bfifty\s*-?\s*ninth\b/, '59th')
|
261
|
+
nsub!(/\bfifty\s*-?\s*eight\b/, '58')
|
262
|
+
nsub!(/\bfifty\s*-?\s*eighth\b/, '58th')
|
263
|
+
nsub!(/\bfifty\s*-?\s*seven\b/, '57')
|
264
|
+
nsub!(/\bfifty\s*-?\s*seventh\b/, '57th')
|
265
|
+
nsub!(/\bfifty\s*-?\s*six\b/, '56')
|
266
|
+
nsub!(/\bfifty\s*-?\s*sixth\b/, '56th')
|
267
|
+
nsub!(/\bfifty\s*-?\s*five\b/, '55')
|
268
|
+
nsub!(/\bfifty\s*-?\s*fifth\b/, '55th')
|
269
|
+
nsub!(/\bfifty\s*-?\s*four\b/, '54')
|
270
|
+
nsub!(/\bfifty\s*-?\s*fourth\b/, '54th')
|
271
|
+
nsub!(/\bfifty\s*-?\s*three\b/, '53')
|
272
|
+
nsub!(/\bfifty\s*-?\s*third\b/, '53rd')
|
273
|
+
nsub!(/\bfifty\s*-?\s*two\b/, '52')
|
274
|
+
nsub!(/\bfifty\s*-?\s*second\b/, '52nd')
|
275
|
+
nsub!(/\bfifty\s*-?\s*one\b/, '51')
|
276
|
+
nsub!(/\bfifty\s*-?\s*first\b/, '51st')
|
277
|
+
nsub!(/\bfifty\b/, '50')
|
278
|
+
nsub!(/\bfiftieth\b/, '50th')
|
279
|
+
nsub!(/\bfourty\s*-?\s*nine\b/, '49')
|
280
|
+
nsub!(/\bfourty\s*-?\s*ninth\b/, '49th')
|
281
|
+
nsub!(/\bfourty\s*-?\s*eight\b/, '48')
|
282
|
+
nsub!(/\bfourty\s*-?\s*eighth\b/, '48th')
|
283
|
+
nsub!(/\bfourty\s*-?\s*seven\b/, '47')
|
284
|
+
nsub!(/\bfourty\s*-?\s*seventh\b/, '47th')
|
285
|
+
nsub!(/\bfourty\s*-?\s*six\b/, '46')
|
286
|
+
nsub!(/\bfourty\s*-?\s*sixth\b/, '46th')
|
287
|
+
nsub!(/\bfourty\s*-?\s*five\b/, '45')
|
288
|
+
nsub!(/\bfourty\s*-?\s*fifth\b/, '45th')
|
289
|
+
nsub!(/\bfourty\s*-?\s*four\b/, '44')
|
290
|
+
nsub!(/\bfourty\s*-?\s*fourth\b/, '44th')
|
291
|
+
nsub!(/\bfourty\s*-?\s*three\b/, '43')
|
292
|
+
nsub!(/\bfourty\s*-?\s*third\b/, '43rd')
|
293
|
+
nsub!(/\bfourty\s*-?\s*two\b/, '42')
|
294
|
+
nsub!(/\bfourty\s*-?\s*second\b/, '42nd')
|
295
|
+
nsub!(/\bfourty\s*-?\s*one\b/, '41')
|
296
|
+
nsub!(/\bfourty\s*-?\s*first\b/, '41st')
|
297
|
+
nsub!(/\bfourty\b/, '40')
|
298
|
+
nsub!(/\bfourtieth\b/, '40th')
|
299
|
+
nsub!(/\bthirty\s*-?\s*nine\b/, '39')
|
300
|
+
nsub!(/\bthirty\s*-?\s*ninth\b/, '39th')
|
301
|
+
nsub!(/\bthirty\s*-?\s*eight\b/, '38')
|
302
|
+
nsub!(/\bthirty\s*-?\s*eighth\b/, '38th')
|
303
|
+
nsub!(/\bthirty\s*-?\s*seven\b/, '37')
|
304
|
+
nsub!(/\bthirty\s*-?\s*seventh\b/, '37th')
|
305
|
+
nsub!(/\bthirty\s*-?\s*six\b/, '36')
|
306
|
+
nsub!(/\bthirty\s*-?\s*sixth\b/, '36th')
|
307
|
+
nsub!(/\bthirty\s*-?\s*five\b/, '35')
|
308
|
+
nsub!(/\bthirty\s*-?\s*fifth\b/, '35th')
|
309
|
+
nsub!(/\bthirty\s*-?\s*four\b/, '34')
|
310
|
+
nsub!(/\bthirty\s*-?\s*fourth\b/, '34th')
|
311
|
+
nsub!(/\bthirty\s*-?\s*three\b/, '33')
|
312
|
+
nsub!(/\bthirty\s*-?\s*third\b/, '33rd')
|
313
|
+
nsub!(/\bthirty\s*-?\s*two\b/, '32')
|
314
|
+
nsub!(/\bthirty\s*-?\s*second\b/, '32nd')
|
315
|
+
nsub!(/\bthirty\s*-?\s*one\b/, '31')
|
316
|
+
nsub!(/\bthirty\s*-?\s*first\b/, '31st')
|
317
|
+
nsub!(/\bthirty\b/, '30')
|
318
|
+
nsub!(/\bthirtieth\b/, '30th')
|
319
|
+
nsub!(/\btwenty\s*-?\s*nine\b/, '29')
|
320
|
+
nsub!(/\btwenty\s*-?\s*ninth\b/, '29th')
|
321
|
+
nsub!(/\btwenty\s*-?\s*eight\b/, '28')
|
322
|
+
nsub!(/\btwenty\s*-?\s*eighth\b/, '28th')
|
323
|
+
nsub!(/\btwenty\s*-?\s*seven\b/, '27')
|
324
|
+
nsub!(/\btwenty\s*-?\s*seventh\b/, '27th')
|
325
|
+
nsub!(/\btwenty\s*-?\s*six\b/, '26')
|
326
|
+
nsub!(/\btwenty\s*-?\s*sixth\b/, '26th')
|
327
|
+
nsub!(/\btwenty\s*-?\s*five\b/, '25')
|
328
|
+
nsub!(/\btwenty\s*-?\s*fifth\b/, '25th')
|
329
|
+
nsub!(/\btwenty\s*-?\s*four\b/, '24')
|
330
|
+
nsub!(/\btwenty\s*-?\s*fourth\b/, '24th')
|
331
|
+
nsub!(/\btwenty\s*-?\s*three\b/, '23')
|
332
|
+
nsub!(/\btwenty\s*-?\s*third\b/, '23rd')
|
333
|
+
nsub!(/\btwenty\s*-?\s*two\b/, '22')
|
334
|
+
nsub!(/\btwenty\s*-?\s*second\b/, '22nd')
|
335
|
+
nsub!(/\btwenty\s*-?\s*one\b/, '21')
|
336
|
+
nsub!(/\btwenty\s*-?\s*first\b/, '21st')
|
337
|
+
nsub!(/\btwenty\b/, '20')
|
338
|
+
nsub!(/\btwentieth\b/, '20th')
|
339
|
+
nsub!(/\bnineteen\b/, '19')
|
340
|
+
nsub!(/\bnineteenth\b/, '19th')
|
341
|
+
nsub!(/\beighteen\b/, '18')
|
342
|
+
nsub!(/\beighteenth\b/, '18th')
|
343
|
+
nsub!(/\bseventeen\b/, '17')
|
344
|
+
nsub!(/\bseventeenth\b/, '17th')
|
345
|
+
nsub!(/\bsixteen\b/, '16')
|
346
|
+
nsub!(/\bsixteenth\b/, '16th')
|
347
|
+
nsub!(/\bfifteen\b/, '15')
|
348
|
+
nsub!(/\bfifteenth\b/, '15th')
|
349
|
+
nsub!(/\bfourteen\b/, '14')
|
350
|
+
nsub!(/\bfourteenth\b/, '14th')
|
351
|
+
nsub!(/\bthirteen/, '13')
|
352
|
+
nsub!(/\bthirteenth/, '13th')
|
353
|
+
nsub!(/\btwelve\b/, '12')
|
354
|
+
nsub!(/\btwelfth\b/, '12th')
|
355
|
+
nsub!(/\beleven\b/, '11')
|
356
|
+
nsub!(/\beleventh\b/, '11th')
|
357
|
+
nsub!(/\bten\b/, '10')
|
358
|
+
nsub!(/\btenth\b/, '10th')
|
359
|
+
nsub!(/\bnine\b/, '9')
|
360
|
+
nsub!(/\bninth\b/, '9th')
|
361
|
+
nsub!(/\beight\b/, '8')
|
362
|
+
nsub!(/\beighth\b/, '8th')
|
363
|
+
nsub!(/\bseven\b/, '7')
|
364
|
+
nsub!(/\bseventh\b/, '7th')
|
365
|
+
nsub!(/\bsix\b/, '6')
|
366
|
+
nsub!(/\bsixth\b/, '6th')
|
367
|
+
nsub!(/\bfive\b/, '5')
|
368
|
+
nsub!(/\bfifth\b/, '5th')
|
369
|
+
nsub!(/\bfour\b/, '4')
|
370
|
+
nsub!(/\bfourth\b/, '4th')
|
371
|
+
nsub!(/\bthree\b/, '3')
|
372
|
+
nsub!(/\bthird\b/, '3rd')
|
373
|
+
nsub!(/\btwo\b/, '2')
|
374
|
+
nsub!(/\bsecond\b/, '2nd')
|
375
|
+
nsub!(/\bone\b/, '1')
|
376
|
+
nsub!(/\bfirst\b/, '1st')
|
377
|
+
nsub!(/\bzero\b/, '0')
|
378
|
+
nsub!(/\bzeroth\b/, '0th')
|
380
379
|
end
|
381
380
|
|
382
381
|
def standardize_am_pm
|
383
|
-
nsub!(/([0-9])(?:\s*)a\b/,'\1am') # allows 5a as 5am
|
384
|
-
nsub!(/([0-9])(?:\s*)p\b/,'\1pm') # allows 5p as 5pm
|
385
|
-
nsub!(/\s+am\b/,'am') # removes any spaces before am, shouldn't I check for preceeding digits?
|
386
|
-
nsub!(/\s+pm\b/,'pm') # removes any spaces before pm, shouldn't I check for preceeding digits?
|
382
|
+
nsub!(/([0-9])(?:\s*)a\b/, '\1am') # allows 5a as 5am
|
383
|
+
nsub!(/([0-9])(?:\s*)p\b/, '\1pm') # allows 5p as 5pm
|
384
|
+
nsub!(/\s+am\b/, 'am') # removes any spaces before am, shouldn't I check for preceeding digits?
|
385
|
+
nsub!(/\s+pm\b/, 'pm') # removes any spaces before pm, shouldn't I check for preceeding digits?
|
387
386
|
end
|
388
387
|
|
389
388
|
def replace_hyphens
|
390
|
-
nsub!(/--?/,' through ')
|
389
|
+
nsub!(/--?/, ' through ')
|
391
390
|
end
|
392
391
|
|
393
392
|
def insert_repeats_before_words_indicating_recurrence_lame
|
394
393
|
comps = query_str.split
|
395
|
-
(daily_index = comps.index(
|
396
|
-
(weekly_index = comps.index(
|
397
|
-
(monthly_index = comps.index(
|
394
|
+
(daily_index = comps.index('daily')) && comps[daily_index - 1] != 'repeats' && comps[daily_index] = 'repeats daily'
|
395
|
+
(weekly_index = comps.index('weekly')) && comps[weekly_index - 1] != 'repeats' && comps[weekly_index] = 'repeats weekly'
|
396
|
+
(monthly_index = comps.index('monthly')) && comps[monthly_index - 1] != 'repeats' && comps[monthly_index] = 'repeats monthly'
|
398
397
|
if (rejoin = comps.join(' ')) != query_str
|
399
|
-
nsub!(/.+/,rejoin)
|
398
|
+
nsub!(/.+/, rejoin)
|
400
399
|
end
|
401
400
|
end
|
402
401
|
|
403
402
|
def insert_space_at_end_of_string_lame
|
404
403
|
# nsub!(/(.+)/,'\1 ') # I don't really want to be notified about this
|
405
|
-
query_str.gsub!(/(.+)/,'\1 ')
|
404
|
+
query_str.gsub!(/(.+)/, '\1 ')
|
406
405
|
end
|
407
406
|
|
408
407
|
def to_s
|
@@ -410,63 +409,64 @@ module Nickel
|
|
410
409
|
end
|
411
410
|
|
412
411
|
private
|
412
|
+
|
413
413
|
attr_accessor :query_str
|
414
414
|
|
415
415
|
def standardize_input
|
416
|
-
nsub!(/last\s+#{DAY_OF_WEEK}/,'5th \1') # last dayname => 5th dayname
|
416
|
+
nsub!(/last\s+#{DAY_OF_WEEK}/, '5th \1') # last dayname => 5th dayname
|
417
417
|
nsub!(/\ba\s+(week|month|day)/, '1 \1') # a month|week|day => 1 month|week|day
|
418
|
-
nsub!(/^(through|until)/,'today through') # ^through => today through
|
419
|
-
nsub!(/every\s*(night|morning)/,'every day')
|
420
|
-
nsub!(/tonight/,'today')
|
421
|
-
nsub!(/this(?:\s*)morning/,'today')
|
422
|
-
nsub!(/before\s+12pm/,'6am to 12pm') # arbitrary
|
418
|
+
nsub!(/^(through|until)/, 'today through') # ^through => today through
|
419
|
+
nsub!(/every\s*(night|morning)/, 'every day')
|
420
|
+
nsub!(/tonight/, 'today')
|
421
|
+
nsub!(/this(?:\s*)morning/, 'today')
|
422
|
+
nsub!(/before\s+12pm/, '6am to 12pm') # arbitrary
|
423
423
|
|
424
424
|
# Handle 'THE' Cases
|
425
425
|
# Attempt to pick out where a user entered 'the' when they really mean 'every'.
|
426
426
|
# For example,
|
427
427
|
# The first of every month and the 22nd of THE month => repeats monthly first xxxxxx repeats monthly 22nd xxxxxxx
|
428
|
-
nsub!(/(?:the\s+)?#{DATE_DD_WITH_SUFFIX}\s+(?:of\s+)?(?:every|each)\s+month((?:.*)of\s+the\s+month(?:.*))/) do |m1,m2|
|
429
|
-
ret_str =
|
428
|
+
nsub!(/(?:the\s+)?#{DATE_DD_WITH_SUFFIX}\s+(?:of\s+)?(?:every|each)\s+month((?:.*)of\s+the\s+month(?:.*))/) do |m1, m2|
|
429
|
+
ret_str = ' repeats monthly ' + m1
|
430
430
|
ret_str << m2.gsub(/(?:and\s+)?(?:the\s+)?#{DATE_DD_WITH_SUFFIX}\s+of\s+the\s+month/, ' repeats monthly \1 ')
|
431
431
|
end
|
432
432
|
|
433
433
|
# Every first sunday of the month and the last tuesday => repeats monthly first sunday xxxxxxxxx repeats monthly last tuesday xxxxxxx
|
434
|
-
nsub!(/every\s+#{WEEK_OF_MONTH}\s+#{DAY_OF_WEEK}\s+of\s+(?:the\s+)?month((?:.*)and\s+(?:the\s+)?#{WEEK_OF_MONTH}\s+#{DAY_OF_WEEK}(?:.*))/) do |m1,m2,m3|
|
435
|
-
ret_str =
|
434
|
+
nsub!(/every\s+#{WEEK_OF_MONTH}\s+#{DAY_OF_WEEK}\s+of\s+(?:the\s+)?month((?:.*)and\s+(?:the\s+)?#{WEEK_OF_MONTH}\s+#{DAY_OF_WEEK}(?:.*))/) do |m1, m2, m3|
|
435
|
+
ret_str = ' repeats monthly ' + m1 + ' ' + m2 + ' '
|
436
436
|
ret_str << m3.gsub(/and\s+(?:the\s+)?#{WEEK_OF_MONTH}\s+#{DAY_OF_WEEK}(?:\s*)(?:of\s+)?(?:the\s+)?(?:month\s+)?/, ' repeats monthly \1 \2 ')
|
437
437
|
end
|
438
438
|
|
439
439
|
# The x through the y of oct z => 10/x/z through 10/y/z
|
440
|
-
nsub!(/(?:the\s+)?#{DATE_DD}\s+(?:through|to|until)\s+(?:the\s+)?#{DATE_DD}\s(?:of\s+)#{MONTH_OF_YEAR}\s+(?:of\s+)?#{YEAR}/) do |m1,m2,m3,m4|
|
440
|
+
nsub!(/(?:the\s+)?#{DATE_DD}\s+(?:through|to|until)\s+(?:the\s+)?#{DATE_DD}\s(?:of\s+)#{MONTH_OF_YEAR}\s+(?:of\s+)?#{YEAR}/) do |m1, m2, m3, m4|
|
441
441
|
(ZDate.months_of_year.index(m3) + 1).to_s + '/' + m1 + '/' + m4 + ' through ' + (ZDate.months_of_year.index(m3) + 1).to_s + '/' + m2 + '/' + m4
|
442
442
|
end
|
443
443
|
|
444
444
|
# The x through the y of oct => 10/x through 10/y
|
445
|
-
nsub!(/(?:the\s+)?#{DATE_DD}\s+(?:through|to|until)\s+(?:the\s+)#{DATE_DD}\s(?:of\s+)?#{MONTH_OF_YEAR}/) do |m1,m2,m3|
|
445
|
+
nsub!(/(?:the\s+)?#{DATE_DD}\s+(?:through|to|until)\s+(?:the\s+)#{DATE_DD}\s(?:of\s+)?#{MONTH_OF_YEAR}/) do |m1, m2, m3|
|
446
446
|
(ZDate.months_of_year.index(m3) + 1).to_s + '/' + m1 + ' through ' + (ZDate.months_of_year.index(m3) + 1).to_s + '/' + m2
|
447
447
|
end
|
448
448
|
|
449
449
|
# January 1 - February 15
|
450
|
-
nsub!(/#{MONTH_OF_YEAR}\s+#{DATE_DD_NB_ON_SUFFIX}\s+(?:through|to|until)\s+#{MONTH_OF_YEAR}\s#{DATE_DD_NB_ON_SUFFIX}/) do |m1,m2,m3,m4|
|
451
|
-
(ZDate.months_of_year.index(m1) + 1).to_s + '/' + m2.gsub(/(st|nd|rd|th)/,
|
450
|
+
nsub!(/#{MONTH_OF_YEAR}\s+#{DATE_DD_NB_ON_SUFFIX}\s+(?:through|to|until)\s+#{MONTH_OF_YEAR}\s#{DATE_DD_NB_ON_SUFFIX}/) do |m1, m2, m3, m4|
|
451
|
+
(ZDate.months_of_year.index(m1) + 1).to_s + '/' + m2.gsub(/(st|nd|rd|th)/, '') + ' through ' + (ZDate.months_of_year.index(m3) + 1).to_s + '/' + m4.gsub(/(st|nd|rd|th)/, '')
|
452
452
|
end
|
453
453
|
|
454
|
-
#Tuesday, january 1 - friday, february 15, 2013
|
455
|
-
nsub!(/(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}\s+(?:through|to|until)\s+(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}(?:[\s,]+)#{YEAR}/) do |m1,m2,m3,m4,m5,m6,m7|
|
454
|
+
# Tuesday, january 1 - friday, february 15, 2013
|
455
|
+
nsub!(/(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}\s+(?:through|to|until)\s+(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}(?:[\s,]+)#{YEAR}/) do |m1, m2, m3, m4, m5, m6, m7|
|
456
456
|
if m7.nil?
|
457
|
-
(ZDate.months_of_year.index(m2) + 1).to_s + '/' + m3.gsub(/(st|nd|rd|th)/,
|
457
|
+
(ZDate.months_of_year.index(m2) + 1).to_s + '/' + m3.gsub(/(st|nd|rd|th)/, '') + ' through ' + (ZDate.months_of_year.index(m5) + 1).to_s + '/' + m6
|
458
458
|
else
|
459
|
-
(ZDate.months_of_year.index(m2) + 1).to_s + '/' + m3.gsub(/(st|nd|rd|th)/,
|
459
|
+
(ZDate.months_of_year.index(m2) + 1).to_s + '/' + m3.gsub(/(st|nd|rd|th)/, '') + '/' + m7 + ' through ' + (ZDate.months_of_year.index(m5) + 1).to_s + '/' + m6.gsub(/(st|nd|rd|th)/, '') + '/' + m7
|
460
460
|
end
|
461
461
|
end
|
462
462
|
|
463
|
-
#Tuesday, january 1 2013 - friday, february 15, 2013
|
464
|
-
nsub!(/(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}\s+#{YEAR}\s+(?:through|to|until)\s+(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}(?:[\s,]+)#{YEAR}/) do |m1,m2,m3,m4,m5,m6,m7,m8|
|
465
|
-
|
463
|
+
# Tuesday, january 1 2013 - friday, february 15, 2013
|
464
|
+
nsub!(/(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}\s+#{YEAR}\s+(?:through|to|until)\s+(?:#{DAY_OF_WEEK})?(?:[\s,]+)#{MONTH_OF_YEAR}(?:[\s,]+)#{DATE_DD}(?:[\s,]+)#{YEAR}/) do |m1, m2, m3, m4, m5, m6, m7, m8|
|
465
|
+
(ZDate.months_of_year.index(m2) + 1).to_s + '/' + m3 + '/' + m4 + ' through ' + (ZDate.months_of_year.index(m6) + 1).to_s + '/' + m7 + '/' + m8
|
466
466
|
end
|
467
467
|
|
468
468
|
# Monthname x through y
|
469
|
-
nsub!(/#{MONTH_OF_YEAR}\s+(?:the\s+)?#{DATE_DD_NB_ON_SUFFIX}\s+(?:of\s+)?(?:#{YEAR}\s+)?(?:through|to|until)\s+(?:the\s+)?#{DATE_DD_NB_ON_SUFFIX}(?:\s+of)?(?:\s+#{YEAR})?/) do |m1,m2,m3,m4,m5|
|
469
|
+
nsub!(/#{MONTH_OF_YEAR}\s+(?:the\s+)?#{DATE_DD_NB_ON_SUFFIX}\s+(?:of\s+)?(?:#{YEAR}\s+)?(?:through|to|until)\s+(?:the\s+)?#{DATE_DD_NB_ON_SUFFIX}(?:\s+of)?(?:\s+#{YEAR})?/) do |m1, m2, m3, m4, m5|
|
470
470
|
if m3 # $3 holds first occurrence of year
|
471
471
|
(ZDate.months_of_year.index(m1) + 1).to_s + '/' + m2 + '/' + m3 + ' through ' + (ZDate.months_of_year.index(m1) + 1).to_s + '/' + m4 + '/' + m3
|
472
472
|
elsif m5 # $5 holds second occurrence of year
|
@@ -479,7 +479,7 @@ module Nickel
|
|
479
479
|
# Monthname x through monthname y
|
480
480
|
# Jan 14 through jan 18 => 1/14 through 1/18
|
481
481
|
# Oct 2 until oct 5
|
482
|
-
nsub!(/#{MONTH_OF_YEAR}\s+#{DATE_DD_NB_ON_SUFFIX}\s+(?:to|through|until)\s+#{MONTH_OF_YEAR}\s+#{DATE_DD_NB_ON_SUFFIX}\s+(?:of\s+)?(?:#{YEAR})?/) do |m1,m2,m3,m4,m5|
|
482
|
+
nsub!(/#{MONTH_OF_YEAR}\s+#{DATE_DD_NB_ON_SUFFIX}\s+(?:to|through|until)\s+#{MONTH_OF_YEAR}\s+#{DATE_DD_NB_ON_SUFFIX}\s+(?:of\s+)?(?:#{YEAR})?/) do |m1, m2, m3, m4, m5|
|
483
483
|
if m5
|
484
484
|
(ZDate.months_of_year.index(m1) + 1).to_s + '/' + m2 + '/' + m5 + ' through ' + (ZDate.months_of_year.index(m3) + 1).to_s + '/' + m4 + '/' + m5 + ' '
|
485
485
|
else
|
@@ -488,12 +488,12 @@ module Nickel
|
|
488
488
|
end
|
489
489
|
|
490
490
|
# Mnday the 23rd, tuesday the 24th and wed the 25th of oct => 11/23 11/24 11/25
|
491
|
-
nsub!(/((?:#{DAY_OF_WEEK_NB}\s+the\s+#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?){1,31})of\s+#{MONTH_OF_YEAR}\s*(#{YEAR})?/) do |m1,m2,m3|
|
491
|
+
nsub!(/((?:#{DAY_OF_WEEK_NB}\s+the\s+#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?){1,31})of\s+#{MONTH_OF_YEAR}\s*(#{YEAR})?/) do |m1, m2, m3|
|
492
492
|
month_str = (ZDate.months_of_year.index(m2) + 1).to_s
|
493
493
|
if m3
|
494
|
-
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1/' + m3)
|
494
|
+
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1/' + m3)
|
495
495
|
else
|
496
|
-
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1')
|
496
|
+
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1')
|
497
497
|
end
|
498
498
|
end
|
499
499
|
|
@@ -501,12 +501,12 @@ module Nickel
|
|
501
501
|
# the 23rd, 24th, and 25th of october => 11/23 11/24 11/25
|
502
502
|
# the 23rd, 24th, and 25th of october 2010 => 11/23/2010 11/24/2010 11/25/2010
|
503
503
|
# monday and tuesday, the 23rd and 24th of july => 7/23 7/24
|
504
|
-
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:day\s+)?(?:in\s+)?(?:of\s+)#{MONTH_OF_YEAR}\s*(#{YEAR})?/) do |m1,m2,m3|
|
504
|
+
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:day\s+)?(?:in\s+)?(?:of\s+)#{MONTH_OF_YEAR}\s*(#{YEAR})?/) do |m1, m2, m3|
|
505
505
|
month_str = (ZDate.months_of_year.index(m2) + 1).to_s
|
506
506
|
if m3
|
507
|
-
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1/' + m3)
|
507
|
+
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1/' + m3)
|
508
508
|
else
|
509
|
-
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1')
|
509
|
+
m1.gsub(/\b(and|the)\b|#{DAY_OF_WEEK}/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1')
|
510
510
|
end
|
511
511
|
end
|
512
512
|
|
@@ -515,21 +515,21 @@ module Nickel
|
|
515
515
|
# Dec 2nd, 3rd, and 5th 2008 => 12/2/2008 12/2/2008 12/5/2008
|
516
516
|
# Mon nov 23rd 08
|
517
517
|
# Dec 2, 3, 5, 2008 => 12/2/2008 12/3/2008 12/5/2008
|
518
|
-
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+((?:(?:the\s+)?#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?){1,31})#{YEAR}/) do |m1,m2,m3|
|
518
|
+
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+((?:(?:the\s+)?#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?){1,31})#{YEAR}/) do |m1, m2, m3|
|
519
519
|
month_str = (ZDate.months_of_year.index(m1) + 1).to_s
|
520
|
-
m2.gsub(/\b(and|the)\b/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1/' + m3)
|
520
|
+
m2.gsub(/\b(and|the)\b/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/, month_str + '/\1/' + m3)
|
521
521
|
end
|
522
522
|
|
523
|
-
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+((?:(?:the\s+)?#{DATE_DD_WITHOUT_SUFFIX_NB}\s+(?:and\s+)?){1,31})#{YEAR}/) do |m1,m2,m3|
|
523
|
+
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+((?:(?:the\s+)?#{DATE_DD_WITHOUT_SUFFIX_NB}\s+(?:and\s+)?){1,31})#{YEAR}/) do |m1, m2, m3|
|
524
524
|
month_str = (ZDate.months_of_year.index(m1) + 1).to_s
|
525
|
-
m2.gsub(/\b(and|the)\b/,'').gsub(/#{DATE_DD_WITHOUT_SUFFIX}/, month_str + '/\1/' + m3)
|
525
|
+
m2.gsub(/\b(and|the)\b/, '').gsub(/#{DATE_DD_WITHOUT_SUFFIX}/, month_str + '/\1/' + m3)
|
526
526
|
end
|
527
527
|
|
528
528
|
# Dec 2nd, 3rd, and 4th => 12/2, 12/3, 12/4
|
529
529
|
# Note: dec 5 9 to 5 will give an error, need to find these and convert to dec 5 from 9 to 5; also dec 3,4, 9 to|through 5 --> dec 3, 4 from 9 through 5
|
530
|
-
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) do |m1,m2|
|
530
|
+
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) do |m1, m2|
|
531
531
|
month_str = (ZDate.months_of_year.index(m1) + 1).to_s
|
532
|
-
m2.gsub(/(and|the)/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/) {month_str + '/' +
|
532
|
+
m2.gsub(/(and|the)/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/) { month_str + '/' + Regexp.last_match(1) } # last match is from the nested match!
|
533
533
|
end
|
534
534
|
|
535
535
|
# Apr 29, 5 - 8pm
|
@@ -544,13 +544,13 @@ module Nickel
|
|
544
544
|
# "dec 2, 3, and 4" --> 12/2, 12/3, 12/4
|
545
545
|
# "mon, tue, wed, dec 2, 3, and 4" --> 12/2, 12/3, 12/4
|
546
546
|
nsub!(/(#{MONTH_OF_YEAR_NB}\s+(?:the\s+)?(?:(?:#{DATE_DD_WITHOUT_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:to|through|until)\s+#{DATE_DD_WITHOUT_SUFFIX_NB})/) { |m1| m1.gsub(/#{DATE_DD_WITHOUT_SUFFIX}\s+(to|through|until)/, 'from \1 through ') }
|
547
|
-
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+(?:the\s+)?((?:#{DATE_DD_WITHOUT_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) do |m1,m2|
|
547
|
+
nsub!(/(?:(?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})?#{MONTH_OF_YEAR}\s+(?:the\s+)?((?:#{DATE_DD_WITHOUT_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) do |m1, m2|
|
548
548
|
month_str = (ZDate.months_of_year.index(m1) + 1).to_s
|
549
|
-
m2.gsub(/(and|the)/,'').gsub(/#{DATE_DD_NB_ON_SUFFIX}/) {month_str + '/' +
|
549
|
+
m2.gsub(/(and|the)/, '').gsub(/#{DATE_DD_NB_ON_SUFFIX}/) { month_str + '/' + Regexp.last_match(1) } # last match is from nested match
|
550
550
|
end
|
551
551
|
|
552
552
|
# "monday 12/6" --> 12/6
|
553
|
-
nsub!(/#{DAY_OF_WEEK_NB}\s+(#{DATE_MM_SLASH_DD})/,'\1')
|
553
|
+
nsub!(/#{DAY_OF_WEEK_NB}\s+(#{DATE_MM_SLASH_DD})/, '\1')
|
554
554
|
|
555
555
|
# "next friday to|until|through the following tuesday" --> 10/12 through 10/16
|
556
556
|
# "next friday through sunday" --> 10/12 through 10/14
|
@@ -558,9 +558,9 @@ module Nickel
|
|
558
558
|
# we are not going to do date calculations here anymore, so instead:
|
559
559
|
# next friday to|until|through the following tuesday" --> next friday through tuesday
|
560
560
|
# next friday and the following sunday --> next friday and sunday
|
561
|
-
nsub!(/next\s+#{DAY_OF_WEEK}\s+(to|until|through|and)\s+(?:the\s+)?(?:following|next)?(?:\s*)#{DAY_OF_WEEK}/) do |m1,m2,m3|
|
561
|
+
nsub!(/next\s+#{DAY_OF_WEEK}\s+(to|until|through|and)\s+(?:the\s+)?(?:following|next)?(?:\s*)#{DAY_OF_WEEK}/) do |m1, m2, m3|
|
562
562
|
connector = (m2 =~ /and/ ? ' ' : ' through ')
|
563
|
-
|
563
|
+
'next ' + m1 + connector + m3
|
564
564
|
end
|
565
565
|
|
566
566
|
# "this friday to|until|through the following tuesday" --> 10/5 through 10/9
|
@@ -569,63 +569,63 @@ module Nickel
|
|
569
569
|
# No longer performing date calculation
|
570
570
|
# this friday and the following monday --> fri mon
|
571
571
|
# this friday through the following tuesday --> fri through tues
|
572
|
-
nsub!(/(?:this\s+)?#{DAY_OF_WEEK}\s+(to|until|through|and)\s+(?:the\s+)?(?:this|following)(?:\s*)#{DAY_OF_WEEK}/) do |m1,m2,m3|
|
572
|
+
nsub!(/(?:this\s+)?#{DAY_OF_WEEK}\s+(to|until|through|and)\s+(?:the\s+)?(?:this|following)(?:\s*)#{DAY_OF_WEEK}/) do |m1, m2, m3|
|
573
573
|
connector = (m2 =~ /and/ ? ' ' : ' through ')
|
574
574
|
m1 + connector + m3
|
575
575
|
end
|
576
576
|
|
577
577
|
# "the wed after next" --> 2 wed from today
|
578
|
-
nsub!(/(?:the\s+)?#{DAY_OF_WEEK}\s+(?:after|following)\s+(?:the\s+)?next/,'2 \1 from today')
|
578
|
+
nsub!(/(?:the\s+)?#{DAY_OF_WEEK}\s+(?:after|following)\s+(?:the\s+)?next/, '2 \1 from today')
|
579
579
|
|
580
580
|
# "mon and tue" --> mon tue
|
581
|
-
nsub!(/(#{DAY_OF_WEEK}\s+and\s+#{DAY_OF_WEEK})(?:\s+and)?/,'\2 \3')
|
581
|
+
nsub!(/(#{DAY_OF_WEEK}\s+and\s+#{DAY_OF_WEEK})(?:\s+and)?/, '\2 \3')
|
582
582
|
|
583
583
|
# "mon wed every week" --> every mon wed
|
584
|
-
nsub!(/((#{DAY_OF_WEEK}(?:\s*)){1,7})(?:of\s+)?(?:every|each)(\s+other)?\s+week/,'every \4 \1')
|
584
|
+
nsub!(/((#{DAY_OF_WEEK}(?:\s*)){1,7})(?:of\s+)?(?:every|each)(\s+other)?\s+week/, 'every \4 \1')
|
585
585
|
|
586
586
|
# "every 2|3 weeks" --> every 2nd|3rd week
|
587
|
-
nsub!(/(?:repeats\s+)?every\s+(2|3)\s+weeks/) {|m1|
|
587
|
+
nsub!(/(?:repeats\s+)?every\s+(2|3)\s+weeks/) { |m1| 'every ' + m1.to_i.ordinalize + ' week' }
|
588
588
|
|
589
589
|
# "every week on mon tue fri" --> every mon tue fri
|
590
|
-
nsub!(/(?:repeats\s+)?every\s+(?:(other|3rd|2nd)\s+)?weeks?\s+(?:\bon\s+)?((?:#{DAY_OF_WEEK_NB}\s+){1,7})/,'every \1 \2')
|
590
|
+
nsub!(/(?:repeats\s+)?every\s+(?:(other|3rd|2nd)\s+)?weeks?\s+(?:\bon\s+)?((?:#{DAY_OF_WEEK_NB}\s+){1,7})/, 'every \1 \2')
|
591
591
|
|
592
592
|
# "every mon and every tue and.... " --> every mon tue ...
|
593
|
-
nsub!(/every\s+#{DAY_OF_WEEK}\s+(?:and\s+)?every\s+#{DAY_OF_WEEK}(?:\s+(?:and\s+)?every\s+#{DAY_OF_WEEK})?(?:\s+(?:and\s+)?every\s+#{DAY_OF_WEEK})?(?:\s+(?:and\s+)?every\s+#{DAY_OF_WEEK})?/,'every \1 \2 \3 \4 \5')
|
593
|
+
nsub!(/every\s+#{DAY_OF_WEEK}\s+(?:and\s+)?every\s+#{DAY_OF_WEEK}(?:\s+(?:and\s+)?every\s+#{DAY_OF_WEEK})?(?:\s+(?:and\s+)?every\s+#{DAY_OF_WEEK})?(?:\s+(?:and\s+)?every\s+#{DAY_OF_WEEK})?/, 'every \1 \2 \3 \4 \5')
|
594
594
|
|
595
595
|
# monday, wednesday, and friday next week at 8
|
596
596
|
nsub!(/((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){1,7})(?:of\s+)?(this|next)\s+week/, '\2 \1')
|
597
597
|
|
598
598
|
# "every day this|next week" --> returns monday through friday of the closest week, kinda stupid
|
599
599
|
# doesn't do that anymore, no date calculations allowed here, instead just formats it nicely for construct finders --> every day this|next week
|
600
|
-
nsub!(/every\s+day\s+(?:of\s+)?(this|the|next)\s+week\b./) {|m1| m1 == 'next' ?
|
600
|
+
nsub!(/every\s+day\s+(?:of\s+)?(this|the|next)\s+week\b./) { |m1| m1 == 'next' ? 'every day next week' : 'every day this week' }
|
601
601
|
|
602
602
|
# "every day for the next week" --> "every day this week"
|
603
603
|
nsub!(/every\s+day\s+for\s+(the\s+)?(next|this)\s+week/, 'every day this week')
|
604
604
|
|
605
605
|
# "this weekend" --> sat sun
|
606
|
-
nsub!(/(every\s+day\s+|both\s+days\s+)?this\s+weekend(\s+on)?(\s+both\s+days|\s+every\s+day|\s+sat\s+sun)?/,'sat sun')
|
606
|
+
nsub!(/(every\s+day\s+|both\s+days\s+)?this\s+weekend(\s+on)?(\s+both\s+days|\s+every\s+day|\s+sat\s+sun)?/, 'sat sun')
|
607
607
|
|
608
608
|
# "this weekend including mon" --> sat sun mon
|
609
|
-
nsub!(/sat\s+sun\s+(and|includ(es?|ing))\s+mon/,'sat sun mon')
|
610
|
-
nsub!(/sat\s+sun\s+(and|includ(es?|ing))\s+fri/,'fri sat sun')
|
609
|
+
nsub!(/sat\s+sun\s+(and|includ(es?|ing))\s+mon/, 'sat sun mon')
|
610
|
+
nsub!(/sat\s+sun\s+(and|includ(es?|ing))\s+fri/, 'fri sat sun')
|
611
611
|
|
612
612
|
# Note: next weekend including monday will now fail. Need to make constructors find "next sat sun mon"
|
613
613
|
# "next weekend" --> next weekend
|
614
|
-
nsub!(/(every\s+day\s+|both\s+days\s+)?next\s+weekend(\s+on)?(\s+both\s+days|\s+every\s+day|\s+sat\s+sun)?/,'next weekend')
|
614
|
+
nsub!(/(every\s+day\s+|both\s+days\s+)?next\s+weekend(\s+on)?(\s+both\s+days|\s+every\s+day|\s+sat\s+sun)?/, 'next weekend')
|
615
615
|
|
616
616
|
# "next weekend including mon" --> next sat sun mon
|
617
|
-
nsub!(/next\s+weekend\s+(and|includ(es?|ing))\s+mon/,'next sat sun mon')
|
618
|
-
nsub!(/next\s+weekend\s+(and|includ(es?|ing))\s+fri/,'next fri sat sun')
|
617
|
+
nsub!(/next\s+weekend\s+(and|includ(es?|ing))\s+mon/, 'next sat sun mon')
|
618
|
+
nsub!(/next\s+weekend\s+(and|includ(es?|ing))\s+fri/, 'next fri sat sun')
|
619
619
|
|
620
620
|
# "every weekend" --> every sat sun
|
621
|
-
nsub!(/every\s+weekend(?:\s+(?:and|includ(?:es?|ing))\s+(mon|fri))?/,'every sat sun' + ' \1') # regarding "every sat sun fri", order should not matter after "every" keyword
|
621
|
+
nsub!(/every\s+weekend(?:\s+(?:and|includ(?:es?|ing))\s+(mon|fri))?/, 'every sat sun' + ' \1') # regarding "every sat sun fri", order should not matter after "every" keyword
|
622
622
|
|
623
623
|
# "weekend" --> sat sun !!! catch all
|
624
|
-
nsub!(/weekend/,'sat sun')
|
624
|
+
nsub!(/weekend/, 'sat sun')
|
625
625
|
|
626
626
|
# "mon through wed" -- > mon tue wed
|
627
627
|
# CATCH ALL FOR SPANS, TRY NOT TO USE THIS
|
628
|
-
nsub!(/#{DAY_OF_WEEK}\s+(?:through|to|until)\s+#{DAY_OF_WEEK}/) do |m1,m2|
|
628
|
+
nsub!(/#{DAY_OF_WEEK}\s+(?:through|to|until)\s+#{DAY_OF_WEEK}/) do |m1, m2|
|
629
629
|
index1 = ZDate.days_of_week.index(m1)
|
630
630
|
index2 = ZDate.days_of_week.index(m2)
|
631
631
|
i = index1
|
@@ -636,10 +636,11 @@ module Nickel
|
|
636
636
|
i += 1
|
637
637
|
end
|
638
638
|
elsif index2 < index1
|
639
|
-
|
639
|
+
loop do
|
640
640
|
ret_string << ZDate.days_of_week[i] + ' '
|
641
641
|
i = (i + 1) % 7
|
642
|
-
|
642
|
+
break if i != index2 + 1 # wrap until it hits index2
|
643
|
+
end
|
643
644
|
else
|
644
645
|
# indices are the same, one week event
|
645
646
|
8.times do
|
@@ -651,132 +652,132 @@ module Nickel
|
|
651
652
|
end
|
652
653
|
|
653
654
|
# "every day" --> repeats daily
|
654
|
-
nsub!(/\b(repeat(?:s|ing)?|every|each)\s+da(ily|y)\b/,'repeats daily')
|
655
|
+
nsub!(/\b(repeat(?:s|ing)?|every|each)\s+da(ily|y)\b/, 'repeats daily')
|
655
656
|
|
656
657
|
# "every other week starting this|next fri" --> every other friday starting this friday
|
657
|
-
nsub!(/every\s+(3rd|other)\s+week\s+(?:start(?:s|ing)?|begin(?:s|ning)?)\s+(this|next)\s+#{DAY_OF_WEEK}/,'every \1 \3 start \2 \3')
|
658
|
+
nsub!(/every\s+(3rd|other)\s+week\s+(?:start(?:s|ing)?|begin(?:s|ning)?)\s+(this|next)\s+#{DAY_OF_WEEK}/, 'every \1 \3 start \2 \3')
|
658
659
|
|
659
660
|
# "every other|3rd friday starting this|next week" --> every other|3rd friday starting this|next friday
|
660
|
-
nsub!(/every\s+(3rd|other)\s+#{DAY_OF_WEEK}\s+(?:start(?:s|ing)?|begin(?:s|ning)?)\s+(this|next)\s+week/,'every \1 \2 start \3 \2')
|
661
|
+
nsub!(/every\s+(3rd|other)\s+#{DAY_OF_WEEK}\s+(?:start(?:s|ing)?|begin(?:s|ning)?)\s+(this|next)\s+week/, 'every \1 \2 start \3 \2')
|
661
662
|
|
662
663
|
# "repeats monthly on the 1st and 2nd friday" --> repeats monthly 1st friday 2nd friday
|
663
664
|
# "repeats every other month on the 1st and 2nd friday" --> repeats monthly 1st friday 2nd friday
|
664
665
|
# "repeats every three months on the 1st and 2nd friday" --> repeats threemonthly 1st friday 2nd friday
|
665
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1,m2|
|
666
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1,m2|
|
667
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1,m2|
|
668
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1,m2|
|
669
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1,m2|
|
670
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1,m2|
|
666
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1, m2| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
667
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1, m2| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
668
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1, m2| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
669
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1, m2| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
670
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1, m2| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
671
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+months?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}/) { |m1, m2| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
671
672
|
|
672
673
|
# "repeats monthly on the 1st friday" --> repeats monthly 1st friday
|
673
674
|
# "repeats monthly on the 1st friday, second tuesday, and third friday" --> repeats monthly 1st friday 2nd tuesday 3rd friday
|
674
675
|
# "repeats every other month on the 1st friday, second tuesday, and third friday" --> repeats monthly 1st friday 2nd tuesday 3rd friday
|
675
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1|
|
676
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1|
|
677
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1|
|
678
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1|
|
679
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1|
|
680
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1|
|
676
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
677
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
678
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
679
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
680
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
681
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
681
682
|
|
682
683
|
# "repeats monthly on the 1st friday saturday" --> repeats monthly 1st friday 1st saturday
|
683
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1,m2|
|
684
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1,m2|
|
685
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1,m2|
|
686
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1,m2|
|
687
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1,m2|
|
688
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1,m2|
|
684
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1, m2| 'repeats monthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
685
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1, m2| 'repeats altmonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
686
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1, m2| 'repeats threemonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
687
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1, m2| 'repeats monthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
688
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1, m2| 'repeats altmonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
689
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+month(?:ly|s)?\s+(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})/) { |m1, m2| 'repeats threemonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
689
690
|
|
690
691
|
# "21st of each month" --> repeats monthly 21st
|
691
692
|
# "on the 21st, 22nd and 25th of each month" --> repeats monthly 21st 22nd 25th
|
692
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:days?\s+)?(?:of\s+)?(?:each|all|every)\s+\bmonths?/) { |m1|
|
693
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:days?\s+)?(?:of\s+)?(?:each|all|every)\s+(?:other|2n?d?)\s+months?/) { |m1|
|
694
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:days?\s+)?(?:of\s+)?(?:each|all|every)\s+3r?d?\s+months?/) { |m1|
|
693
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:days?\s+)?(?:of\s+)?(?:each|all|every)\s+\bmonths?/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
694
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:days?\s+)?(?:of\s+)?(?:each|all|every)\s+(?:other|2n?d?)\s+months?/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
695
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,31})(?:days?\s+)?(?:of\s+)?(?:each|all|every)\s+3r?d?\s+months?/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
695
696
|
|
696
697
|
# "repeats each month on the 22nd" --> repeats monthly 22nd
|
697
698
|
# "repeats monthly on the 22nd 23rd and 24th" --> repeats monthly 22nd 23rd 24th
|
698
699
|
# This can ONLY handle multi-day recurrence WITHOUT independent times for each, i.e. "repeats monthly on the 22nd at noon and 24th from 1 to 9" won't work; that's going to be a tricky one.
|
699
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
700
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
701
|
-
#nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?\bmonth(?:s|ly)\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| "repeats monthly " + m1.gsub(/\b(and|the)\b/,'') + " "}
|
702
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?\bmonthly\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
703
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
704
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
705
|
-
#nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:s|ly)\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| "repeats altmonthly " + m1.gsub(/\b(and|the)\b/,'') + " "}
|
706
|
-
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
707
|
-
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
708
|
-
#nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?3r?d?\s+month(?:s|ly)\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| "repeats threemonthly " + m1.gsub(/\b(and|the)\b/,'') + " "}
|
700
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)\bmonth(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
701
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?\bmonth(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
702
|
+
# nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?\bmonth(?:s|ly)\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| "repeats monthly " + m1.gsub(/\b(and|the)\b/,'') + " "}
|
703
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?\bmonthly\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
704
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)(?:other|2n?d?)\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
705
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
706
|
+
# nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?(?:other|2n?d?)\s+month(?:s|ly)\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| "repeats altmonthly " + m1.gsub(/\b(and|the)\b/,'') + " "}
|
707
|
+
nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)3r?d?\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
708
|
+
nsub!(/(?:repeats\s+)(?:(?:each|every|all)\s+)?3r?d?\s+month(?:s|ly)?\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
709
|
+
# nsub!(/(?:repeats\s+)?(?:(?:each|every|all)\s+)?3r?d?\s+month(?:s|ly)\s+(?:on\s+)?(?:the\s+)?((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| "repeats threemonthly " + m1.gsub(/\b(and|the)\b/,'') + " "}
|
709
710
|
|
710
711
|
# "on day 4 of every month" --> repeats monthly 4
|
711
712
|
# "on days 4 9 and 14 of every month" --> repeats monthly 4 9 14
|
712
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:day|date)s?\s+((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)(every|all|each)\s+\bmonths?/) { |m1|
|
713
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:day|date)s?\s+((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)(every|all|each)\s+(?:other|2n?d?)\s+months?/) { |m1|
|
714
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:day|date)s?\s+((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)(every|all|each)\s+3r?d?\s+months?/) { |m1|
|
713
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:day|date)s?\s+((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)(every|all|each)\s+\bmonths?/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
714
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:day|date)s?\s+((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)(every|all|each)\s+(?:other|2n?d?)\s+months?/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
715
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:day|date)s?\s+((?:#{DATE_DD_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)(every|all|each)\s+3r?d?\s+months?/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
715
716
|
|
716
717
|
# "every 22nd of the month" --> repeats monthly 22
|
717
718
|
# "every 22nd 23rd and 25th of the month" --> repeats monthly 22 23 25
|
718
|
-
nsub!(/(?:repeats\s+)?(?:every|each)\s+((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:day\s+)?(?:of\s+)?(?:the\s+)?\bmonth/) { |m1|
|
719
|
-
nsub!(/(?:repeats\s+)?(?:every|each)\s+other\s+((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:day\s+)?(?:of\s+)?(?:the\s+)?\bmonth/) { |m1|
|
719
|
+
nsub!(/(?:repeats\s+)?(?:every|each)\s+((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:day\s+)?(?:of\s+)?(?:the\s+)?\bmonth/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
720
|
+
nsub!(/(?:repeats\s+)?(?:every|each)\s+other\s+((?:#{DATE_DD_WITH_SUFFIX_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:day\s+)?(?:of\s+)?(?:the\s+)?\bmonth/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
720
721
|
|
721
722
|
# "every 1st and 2nd fri of the month" --> repeats monthly 1st fri 2nd fri
|
722
|
-
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1,m2|
|
723
|
-
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+other\s+((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1,m2|
|
723
|
+
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1, m2| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
724
|
+
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+other\s+((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1, m2| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
724
725
|
|
725
726
|
# "every 1st friday of the month" --> repeats monthly 1st friday
|
726
727
|
# "every 1st friday and 2nd tuesday of the month" --> repeats monthly 1st friday 2nd tuesday
|
727
|
-
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1|
|
728
|
-
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+other\s+((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1|
|
728
|
+
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
729
|
+
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+other\s+((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
729
730
|
|
730
731
|
# "every 1st fri sat of the month" --> repeats monthly 1st fri 1st sat
|
731
|
-
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1,m2|
|
732
|
-
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+other\s+(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1,m2|
|
732
|
+
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1, m2| 'repeats monthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
733
|
+
nsub!(/(?:repeats\s+)?(?:each|every|all)\s+other\s+(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:the\s+)?(?:(?:each|every|all)\s+)?\bmonths?/) { |m1, m2| 'repeats altmonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
733
734
|
|
734
735
|
# "the 1st and 2nd friday of every month" --> repeats monthly 1st friday 2nd friday
|
735
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all)\s+)\bmonths?/) { |m1,m2|
|
736
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all)\s+)(?:other|2n?d?)\s+months?/) { |m1,m2|
|
737
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all)\s+)3r?d?\s+months?/) { |m1,m2|
|
736
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all)\s+)\bmonths?/) { |m1, m2| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
737
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all)\s+)(?:other|2n?d?)\s+months?/) { |m1, m2| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
738
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all)\s+)3r?d?\s+months?/) { |m1, m2| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
738
739
|
|
739
740
|
# "the 1st friday of every month" --> repeats monthly 1st friday
|
740
741
|
# "the 1st friday and the 2nd tuesday of every month" --> repeats monthly 1st friday 2nd tuesday
|
741
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all)\s+)\bmonths?/) { |m1|
|
742
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all)\s+)(?:other|2n?d?)\s+months?/) { |m1|
|
743
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all)\s+)3r?d?\s+months?/) { |m1|
|
742
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all)\s+)\bmonths?/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
743
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all)\s+)(?:other|2n?d?)\s+months?/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
744
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all)\s+)3r?d?\s+months?/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
744
745
|
|
745
746
|
# "the 1st friday saturday of every month" --> repeats monthly 1st friday 1st saturday
|
746
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all)\s+)\bmonths?/) { |m1,m2|
|
747
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all)\s+)(?:other|2n?d?)\s+months?/) { |m1,m2|
|
748
|
-
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all)\s+)3r?d?\s+months?/) { |m1,m2|
|
747
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all)\s+)\bmonths?/) { |m1, m2| 'repeats monthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
748
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all)\s+)(?:other|2n?d?)\s+months?/) { |m1, m2| 'repeats altmonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
749
|
+
nsub!(/(?:repeats\s+)?(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all)\s+)3r?d?\s+months?/) { |m1, m2| 'repeats threemonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
749
750
|
|
750
751
|
# "repeats on the 1st and second friday of the month" --> repeats monthly 1st friday 2nd friday
|
751
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all|the)\s+)?\bmonths?/) { |m1,m2|
|
752
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all|the)\s+)?(?:other|2n?d?)\s+months?/) { |m1,m2|
|
753
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all|the)\s+)?3r?d?\s+months?/) { |m1,m2|
|
752
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all|the)\s+)?\bmonths?/) { |m1, m2| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
753
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all|the)\s+)?(?:other|2n?d?)\s+months?/) { |m1, m2| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
754
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,5})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:(?:every|each|all|the)\s+)?3r?d?\s+months?/) { |m1, m2| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '').split.join(' ' + m2 + ' ') + ' ' + m2 + ' ' }
|
754
755
|
|
755
756
|
# "repeats on the 1st friday of the month --> repeats monthly 1st friday
|
756
757
|
# "repeats on the 1st friday and second tuesday of the month" --> repeats monthly 1st friday 2nd tuesday
|
757
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all|the)\s+)?\bmonths?/) { |m1|
|
758
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all|the)\s+)?(?:other|2n?d?)\s+months?/) { |m1|
|
759
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all|the)\s+)?3r?d?\s+months?/) { |m1|
|
758
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all|the)\s+)?\bmonths?/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
759
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all|the)\s+)?(?:other|2n?d?)\s+months?/) { |m1| 'repeats altmonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
760
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:(?:every|each|all|the)\s+)?3r?d?\s+months?/) { |m1| 'repeats threemonthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
760
761
|
|
761
762
|
# "repeats on the 1st friday saturday of the month" --> repeats monthly 1st friday 1st saturday
|
762
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all|the)\s+)?\bmonths?/) { |m1,m2|
|
763
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all|the)\s+)?(?:other|2n?d?)\s+months?/) { |m1,m2|
|
764
|
-
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all|the)\s+)?3r?d?\s+months?/) { |m1,m2|
|
763
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all|the)\s+)?\bmonths?/) { |m1, m2| 'repeats monthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
764
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all|the)\s+)?(?:other|2n?d?)\s+months?/) { |m1, m2| 'repeats altmonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
765
|
+
nsub!(/(?:repeats\s+)(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+){2,7})(?:of\s+)?(?:(?:every|each|all|the)\s+)?3r?d?\s+months?/) { |m1, m2| 'repeats threemonthly ' + m1 + ' ' + m2.split.join(' ' + m1 + ' ') + ' ' }
|
765
766
|
|
766
767
|
# "repeats each month" --> every month
|
767
|
-
nsub!(/(repeats\s+)?(each|every)\s+\bmonth(ly)?/,'every month ')
|
768
|
-
nsub!(/all\s+months/,'every month')
|
768
|
+
nsub!(/(repeats\s+)?(each|every)\s+\bmonth(ly)?/, 'every month ')
|
769
|
+
nsub!(/all\s+months/, 'every month')
|
769
770
|
|
770
771
|
# "repeats every other month" --> every other month
|
771
|
-
nsub!(/(repeats\s+)?(each|every)\s+(other|2n?d?)\s+month(ly)?/,'every other month ')
|
772
|
-
nsub!(/(repeats\s+)?bimonthly/,'every other month ') # hyphens have already been replaced in spell check (bi-monthly)
|
772
|
+
nsub!(/(repeats\s+)?(each|every)\s+(other|2n?d?)\s+month(ly)?/, 'every other month ')
|
773
|
+
nsub!(/(repeats\s+)?bimonthly/, 'every other month ') # hyphens have already been replaced in spell check (bi-monthly)
|
773
774
|
|
774
775
|
# "repeats every three months" --> every third month
|
775
|
-
nsub!(/(repeats\s+)?(each|every)\s+3r?d?\s+month/,'every third month ')
|
776
|
-
nsub!(/(repeats\s+)?trimonthly/,'every third month ')
|
776
|
+
nsub!(/(repeats\s+)?(each|every)\s+3r?d?\s+month/, 'every third month ')
|
777
|
+
nsub!(/(repeats\s+)?trimonthly/, 'every third month ')
|
777
778
|
|
778
779
|
# All months
|
779
|
-
nsub!(/(repeats\s+)?all\s+months/,'every month ')
|
780
|
+
nsub!(/(repeats\s+)?all\s+months/, 'every month ')
|
780
781
|
nsub!(/(repeats\s+)?all\s+other\+months/, 'every other month ')
|
781
782
|
|
782
783
|
# All month
|
@@ -785,16 +786,16 @@ module Nickel
|
|
785
786
|
|
786
787
|
# "repeats 2nd mon" --> repeats monthly 2nd mon
|
787
788
|
# "repeats 2nd mon, 3rd fri, and the last sunday" --> repeats monthly 2nd mon 3rd fri 5th sun
|
788
|
-
nsub!(/repeats\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1|
|
789
|
+
nsub!(/repeats\s+(?:\bon\s+)?(?:the\s+)?((?:(?:1|2|3|4|5)(?:st|nd|rd|th)?\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') + ' ' }
|
789
790
|
|
790
791
|
# "starting at x, ending at y" --> from x to y
|
791
|
-
nsub!(/(?:begin|start)(?:s|ing|ning)?\s+(?:at\s+)?#{TIME}\s+(?:and\s+)?end(?:s|ing)?\s+(?:at\s+)#{TIME}/,'from \1 to \2')
|
792
|
+
nsub!(/(?:begin|start)(?:s|ing|ning)?\s+(?:at\s+)?#{TIME}\s+(?:and\s+)?end(?:s|ing)?\s+(?:at\s+)#{TIME}/, 'from \1 to \2')
|
792
793
|
|
793
794
|
# "the x through the y"
|
794
|
-
nsub!(/^(?:the\s+)?#{DATE_DD_WITH_SUFFIX}\s+(?:through|to|until)\s+(?:the\s+)?#{DATE_DD_WITH_SUFFIX}$/,'\1 through \2 ')
|
795
|
+
nsub!(/^(?:the\s+)?#{DATE_DD_WITH_SUFFIX}\s+(?:through|to|until)\s+(?:the\s+)?#{DATE_DD_WITH_SUFFIX}$/, '\1 through \2 ')
|
795
796
|
|
796
797
|
# "x week(s) away" --> x week(s) from now
|
797
|
-
nsub!(/([0-9]+)\s+(day|week|month)s?\s+away/,'\1 \2s from now')
|
798
|
+
nsub!(/([0-9]+)\s+(day|week|month)s?\s+away/, '\1 \2s from now')
|
798
799
|
|
799
800
|
# "x days from now" --> "x days from now"
|
800
801
|
# "in 2 weeks|days|months" --> 2 days|weeks|months from now"
|
@@ -813,22 +814,22 @@ module Nickel
|
|
813
814
|
nsub!(/^(?:\s*)(?:right\s+)?now(?:\s*)$/, '0 minutes from now')
|
814
815
|
|
815
816
|
# "a week/month from yesterday|tomorrow" --> 1 week from yesterday|tomorrow
|
816
|
-
nsub!(/(?:(?:a|1)\s+)?(week|month)\s+from\s+(yesterday|tomorrow)/,'1 \1 from \2')
|
817
|
+
nsub!(/(?:(?:a|1)\s+)?(week|month)\s+from\s+(yesterday|tomorrow)/, '1 \1 from \2')
|
817
818
|
|
818
819
|
# "a week/month from yesterday|tomorrow" --> 1 week from monday
|
819
|
-
nsub!(/(?:(?:a|1)\s+)?(week|month)\s+from\s+#{DAY_OF_WEEK}/,'1 \1 from \2')
|
820
|
+
nsub!(/(?:(?:a|1)\s+)?(week|month)\s+from\s+#{DAY_OF_WEEK}/, '1 \1 from \2')
|
820
821
|
|
821
822
|
# "every 2|3 days" --> every 2nd|3rd day
|
822
|
-
nsub!(/every\s+(2|3)\s+days?/) {|m1|
|
823
|
+
nsub!(/every\s+(2|3)\s+days?/) { |m1| 'every ' + m1.to_i.ordinalize + ' day' }
|
823
824
|
|
824
825
|
# "the following" --> following
|
825
|
-
nsub!(/the\s+following/,'following')
|
826
|
+
nsub!(/the\s+following/, 'following')
|
826
827
|
|
827
828
|
# "friday the 12th to sunday the 14th" --> 12th through 14th
|
828
|
-
nsub!(/#{DAY_OF_WEEK}\s+the\s+#{DATE_DD_WITH_SUFFIX}\s+(?:to|through|until)\s+#{DAY_OF_WEEK}\s+the\s+#{DATE_DD_WITH_SUFFIX}/,'\2 through \4')
|
829
|
+
nsub!(/#{DAY_OF_WEEK}\s+the\s+#{DATE_DD_WITH_SUFFIX}\s+(?:to|through|until)\s+#{DAY_OF_WEEK}\s+the\s+#{DATE_DD_WITH_SUFFIX}/, '\2 through \4')
|
829
830
|
|
830
831
|
# "between 1 and 4" --> from 1 to 4
|
831
|
-
nsub!(/between\s+#{TIME}\s+and\s+#{TIME}/,'from \1 to \2')
|
832
|
+
nsub!(/between\s+#{TIME}\s+and\s+#{TIME}/, 'from \1 to \2')
|
832
833
|
|
833
834
|
# "on the 3rd sat of this month" --> "3rd sat this month"
|
834
835
|
# "on the 3rd sat and 5th tuesday of this month" --> "3rd sat this month 5th tuesday this month"
|
@@ -836,45 +837,45 @@ module Nickel
|
|
836
837
|
# "on the 2nd and 3rd sat of this month" --> "2nd sat this month 3rd sat this month"
|
837
838
|
# This is going to be dicey, I'm going to remove 'the' from the following regexprsns:
|
838
839
|
# The 'the' case will be handled AFTER wrapper substitution at end of this method
|
839
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:this|of)\s+month/) { |m1,m2| m2.gsub(/\band\b/,'').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 this month') }
|
840
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:this|of)\s+month/) { |m1,m2| m1.gsub(/\b(and|the)\b/,'').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' this month') }
|
841
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:this|of)\s+month/) { |m1| m1.gsub(/\b(and|the)\b/,'').gsub(/#{DAY_OF_WEEK}/,'\1 this month') }
|
840
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:this|of)\s+month/) { |m1, m2| m2.gsub(/\band\b/, '').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 this month') }
|
841
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:this|of)\s+month/) { |m1, m2| m1.gsub(/\b(and|the)\b/, '').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' this month') }
|
842
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:this|of)\s+month/) { |m1| m1.gsub(/\b(and|the)\b/, '').gsub(/#{DAY_OF_WEEK}/, '\1 this month') }
|
842
843
|
|
843
844
|
# "on the 3rd sat of next month" --> "3rd sat next month"
|
844
845
|
# "on the 3rd sat and 5th tuesday of next month" --> "3rd sat next month 5th tuesday next month"
|
845
846
|
# "on the 3rd sat and sunday of next month" --> "3rd sat this month 3rd sun next month"
|
846
847
|
# "on the 2nd and 3rd sat of next month" --> "2nd sat this month 3rd sat next month"
|
847
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?next\s+month/) { |m1,m2| m2.gsub(/\band\b/,'').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 next month') }
|
848
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?next\s+month/) { |m1,m2| m1.gsub(/\b(and|the)\b/,'').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' next month') }
|
849
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?next\s+month/) { |m1| m1.gsub(/\b(and|the)\b/,'').gsub(/#{DAY_OF_WEEK}/,'\1 next month') }
|
848
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?next\s+month/) { |m1, m2| m2.gsub(/\band\b/, '').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 next month') }
|
849
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?next\s+month/) { |m1, m2| m1.gsub(/\b(and|the)\b/, '').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' next month') }
|
850
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?next\s+month/) { |m1| m1.gsub(/\b(and|the)\b/, '').gsub(/#{DAY_OF_WEEK}/, '\1 next month') }
|
850
851
|
|
851
852
|
# "on the 3rd sat of nov" --> "3rd sat nov"
|
852
853
|
# "on the 3rd sat and 5th tuesday of nov" --> "3rd sat nov 5th tuesday nov !!!!!!! walking a fine line here, 'nov 5th', but then again the entire nlp walks a pretty fine line
|
853
854
|
# "on the 3rd sat and sunday of nov" --> "3rd sat nov 3rd sun nov"
|
854
855
|
# "on the 2nd and 3rd sat of nov" --> "2nd sat nov 3rd sat nov"
|
855
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/) { |m1,m2,m3| m2.gsub(/\band\b/,'').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 ' + m3) }
|
856
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/) { |m1,m2,m3| m1.gsub(/\b(and|the)\b/,'').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' ' + m3) }
|
857
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/) { |m1,m2| m1.gsub(/\b(and|the)\b/,'').gsub(/#{DAY_OF_WEEK}/,'\1 ' + m2) }
|
856
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/) { |m1, m2, m3| m2.gsub(/\band\b/, '').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 ' + m3) }
|
857
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/) { |m1, m2, m3| m1.gsub(/\b(and|the)\b/, '').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' ' + m3) }
|
858
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/) { |m1, m2| m1.gsub(/\b(and|the)\b/, '').gsub(/#{DAY_OF_WEEK}/, '\1 ' + m2) }
|
858
859
|
|
859
860
|
# "on the last day of nov" --> "last day nov"
|
860
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?last\s+day\s+(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/,'last day \1')
|
861
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?last\s+day\s+(?:of\s+)?(?:in\s+)?#{MONTH_OF_YEAR}/, 'last day \1')
|
861
862
|
# "on the 1st|last day of this|the month" --> "1st|last day this month"
|
862
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|last)\s+day\s+(?:of\s+)?(?:this|the)?(?:\s*)month/,'\1 day this month')
|
863
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|last)\s+day\s+(?:of\s+)?(?:this|the)?(?:\s*)month/, '\1 day this month')
|
863
864
|
# "on the 1st|last day of next month" --> "1st|last day next month"
|
864
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|last)\s+day\s+(?:of\s+)?next\s+month/,'\1 day next month')
|
865
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|last)\s+day\s+(?:of\s+)?next\s+month/, '\1 day next month')
|
865
866
|
|
866
867
|
# "every other weekend" --> every other sat sun
|
867
|
-
nsub!(/every\s+other\s+weekend/,'every other sat sun')
|
868
|
+
nsub!(/every\s+other\s+weekend/, 'every other sat sun')
|
868
869
|
|
869
870
|
# "this week on mon "--> this mon
|
870
|
-
nsub!(/this\s+week\s+(?:on\s+)?#{DAY_OF_WEEK}/,'this \1')
|
871
|
+
nsub!(/this\s+week\s+(?:on\s+)?#{DAY_OF_WEEK}/, 'this \1')
|
871
872
|
# "mon of this week " --> this mon
|
872
|
-
nsub!(/#{DAY_OF_WEEK}\s+(?:of\s+)?this\s+week/,'this \1')
|
873
|
+
nsub!(/#{DAY_OF_WEEK}\s+(?:of\s+)?this\s+week/, 'this \1')
|
873
874
|
|
874
875
|
# "next week on mon "--> next mon
|
875
|
-
nsub!(/next\s+week\s+(?:on\s+)?#{DAY_OF_WEEK}/,'next \1')
|
876
|
+
nsub!(/next\s+week\s+(?:on\s+)?#{DAY_OF_WEEK}/, 'next \1')
|
876
877
|
# "mon of next week " --> next mon
|
877
|
-
nsub!(/#{DAY_OF_WEEK}\s+(?:of\s+)?next\s+week/,'next \1')
|
878
|
+
nsub!(/#{DAY_OF_WEEK}\s+(?:of\s+)?next\s+week/, 'next \1')
|
878
879
|
|
879
880
|
# Ordinal this month:
|
880
881
|
# this will slip by now
|
@@ -897,7 +898,7 @@ module Nickel
|
|
897
898
|
nsub!(/(?:next|the\s+following)\s+month\s+(?:(?:on|the)\s+)?(?:(?:on|the)\s+)?#{DATE_DD}/, '\1 next month')
|
898
899
|
|
899
900
|
# "for the next 3 days|weeks|months" --> for 3 days|weeks|months
|
900
|
-
nsub!(/for\s+(?:the\s+)?(?:next|following)\s+(\d+)\s+(days|weeks|months)/,'for \1 \2')
|
901
|
+
nsub!(/for\s+(?:the\s+)?(?:next|following)\s+(\d+)\s+(days|weeks|months)/, 'for \1 \2')
|
901
902
|
|
902
903
|
# This monthname -> monthname
|
903
904
|
nsub!(/this\s+#{MONTH_OF_YEAR}/, '\1')
|
@@ -915,41 +916,40 @@ module Nickel
|
|
915
916
|
|
916
917
|
# clean up wrapper terminology
|
917
918
|
# This should always be at end of pre-process
|
918
|
-
nsub!(/(begin(s|ning)?|start(s|ing)?)(\s+(at|on))?/,'start')
|
919
|
-
nsub!(/(\bend(s|ing)?|through|until)(\s+(at|on))?/,'through')
|
920
|
-
nsub!(/start\s+(?:(?:this|in)\s+)?#{MONTH_OF_YEAR}/,'start \1')
|
919
|
+
nsub!(/(begin(s|ning)?|start(s|ing)?)(\s+(at|on))?/, 'start')
|
920
|
+
nsub!(/(\bend(s|ing)?|through|until)(\s+(at|on))?/, 'through')
|
921
|
+
nsub!(/start\s+(?:(?:this|in)\s+)?#{MONTH_OF_YEAR}/, 'start \1')
|
921
922
|
|
922
923
|
# 'the' cases; what this is all about is if someone enters "first sunday of the month" they mean one date. But if someone enters "first sunday of the month until december 2nd" they mean recurring
|
923
924
|
# Do these actually do ANYTHING anymore?
|
924
925
|
# "on the 3rd sat and sunday of the month" --> "repeats monthly 3rd sat 3rd sun" OR "3rd sat this month 3rd sun this month"
|
925
926
|
if query_str =~ /(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:the)\s+month/
|
926
927
|
if query_str =~ /(start|through)\s+#{DATE_MM_SLASH_DD}/
|
927
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:the)\s+month/) {|m1,m2|
|
928
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:the)\s+month/) { |m1, m2| 'repeats monthly ' + m2.gsub(/\band\b/, '').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1') }
|
928
929
|
else
|
929
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:the)\s+month/) {|m1,m2| m2.gsub(/\band\b/,'').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 this month') }
|
930
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?(1st|2nd|3rd|4th|5th)\s+((?:#{DAY_OF_WEEK_NB}\s+(?:and\s+)?){2,7})(?:of\s+)?(?:the)\s+month/) { |m1, m2| m2.gsub(/\band\b/, '').gsub(/#{DAY_OF_WEEK}/, m1 + ' \1 this month') }
|
930
931
|
end
|
931
932
|
end
|
932
933
|
|
933
934
|
# "on the 2nd and 3rd sat of this month" --> "repeats monthly 2nd sat 3rd sat" OR "2nd sat this month 3rd sat this month"
|
934
935
|
if query_str =~ /(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the)\s+month/
|
935
936
|
if query_str =~ /(start|through)\s+#{DATE_MM_SLASH_DD}/
|
936
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the)\s+month/) {|m1,m2|
|
937
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the)\s+month/) { |m1, m2| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2) }
|
937
938
|
else
|
938
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the)\s+month/) {|m1,m2| m1.gsub(/\b(and|the)\b/,'').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' this month') }
|
939
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+(?:and\s+)?(?:the\s+)?){2,7})#{DAY_OF_WEEK}\s+(?:of\s+)?(?:the)\s+month/) { |m1, m2| m1.gsub(/\b(and|the)\b/, '').gsub(/(1st|2nd|3rd|4th|5th)/, '\1 ' + m2 + ' this month') }
|
939
940
|
end
|
940
941
|
end
|
941
942
|
|
942
943
|
# "on the 3rd sat and 5th tuesday of this month" --> "repeats monthly 3rd sat 5th tue" OR "3rd sat this month 5th tuesday this month"
|
943
944
|
if query_str =~ /(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the)\s+month/
|
944
945
|
if query_str =~ /(start|through)\s+#{DATE_MM_SLASH_DD}/
|
945
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the)\s+month/) { |m1|
|
946
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the)\s+month/) { |m1| 'repeats monthly ' + m1.gsub(/\b(and|the)\b/, '') }
|
946
947
|
else
|
947
|
-
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the)\s+month/) { |m1| m1.gsub(/\b(and|the)\b/,'').gsub(/#{DAY_OF_WEEK}/,'\1 this month') }
|
948
|
+
nsub!(/(?:\bon\s+)?(?:the\s+)?((?:(?:1st|2nd|3rd|4th|5th)\s+#{DAY_OF_WEEK_NB}\s+(?:and\s+)?(?:the\s+)?){1,10})(?:of\s+)?(?:the)\s+month/) { |m1| m1.gsub(/\b(and|the)\b/, '').gsub(/#{DAY_OF_WEEK}/, '\1 this month') }
|
948
949
|
end
|
949
950
|
end
|
950
951
|
|
951
|
-
nsub!(/from\s+now\s+(through|to|until)/,'now through')
|
952
|
+
nsub!(/from\s+now\s+(through|to|until)/, 'now through')
|
952
953
|
end
|
953
954
|
end
|
954
955
|
end
|
955
|
-
|