這將允許您確定字符串是否表示整數或日期對象的有效範圍,如果是,則返回範圍。
代碼
R =/
\A # match beginning of string
(.+?) # match one or more characters lazily in capture group 1
(\.{2,3}) # match 2 or 3 dots in capture group 2
([^.]+) # match any characters other than dot in capture group 3
\z # match end of string
/x # extended mode
require 'date'
def convert_to_range(str)
str[R]
return nil unless $1
e1 = $1.strip
e2 = $3.strip
exclude_end = ($2.size == 3)
return nil if e1[/\s/] || e2[/\s/]
# Range of integers?
return rng(e1.to_i, e2.to_i, exclude_end) if e1[/\A\d+\z/] && e2[/\A\d+\z/]
# Range of dates?
begin
d1 = Date.parse(e1)
d2 = Date.parse(e2)
return rng(d1, d2, exclude_end)
rescue ArgumentError
end
nil
end
def rng(e1,e2,exclude_end)
Range.new(e1, e2, exclude_end)
end
例子
convert_to_range " 1 .. 20 "
#=> 1..20
convert_to_range "1...20"
#=> 1...20
convert_to_range "20..1"
#=> 20..1
convert_to_range("20..1").size
#=> 0
convert_to_range "1 2..20"
#=> nil
convert_to_range "1 2...20"
#=> nil
convert_to_range "12..2 0"
#=> nil
convert_to_range "1....10"
#=> nil
convert_to_range "1.10"
#=> nil
convert_to_range "1.10"
#=> nil
convert_to_range "2015-06-10...2015-06-19"
#=> #<Date: 2015-06-10 ((2457184j,0s,0n),+0s,2299161j)>...
# #<Date: 2015-06-19 ((2457193j,0s,0n),+0s,2299161j)>
convert_to_range "2015-06-19...2015-06-10"
#=> #<Date: 2015-06-19 ((2457193j,0s,0n),+0s,2299161j)>...
# #<Date: 2015-06-10 ((2457184j,0s,0n),+0s,2299161j)>
convert_to_range "2015-06-10...cat"
#=> nil
在該範圍的端點任意表達式,或者他們是恆定的整數? – nneonneo
端點不僅限於整數。一個有意義的案例:'「2015-06-10 ... 2015-06-19」'日期範圍。 – yeyo
以句號開頭的數字在Ruby中不僅在範圍之後,而且在任何地方都是無效的。你確定條件3嗎? – sawa