Rustam Gasanov
Rustam Gasanov

Reputation: 15781

Ruby wrap dates in string with quotes

I have a string from file that looks like this:

"[[5473, 992, 'smth', Tue, 25 Mar 2014 05:08:12 UTC +00:00, Fri, 07 Mar 2014 22:55:42 UTC +00:00], [5473, 993, 'smth', Tue, 25 Mar 2014 14:38:05 UTC +00:00, Fri, 07 Mar 2014 22:57:33 UTC +00:00], [6084, 994, 'smth', Mon, 24 Mar 2014 23:37:37 UTC +00:00, Mon, 24 Mar 2014 23:37:37 UTC +00:00], [6084, 995, 'smth', nil, nil], [6084, 996, 'smth', nil, nil], [6084, 997, 'smth', nil, nil], [6084, 998, 'smth', nil, nil]]"

To correctly eval it as an array I need to wrap dates with quotes, I have created a regexp for cases when date is in the middle of an array:

(\s)\w{3},\s\d{2}\s\w{3}\s\d{4}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\+00:00(,)

and when date ends with ] symbol:

(\s)\w{3},\s\d{2}\s\w{3}\s\d{4}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\+00:00(])

now I want to replace \1 to " '" and \2 to "'," or "']" correspondingly, with what ruby method I can accomplish my task?

Upvotes: 0

Views: 465

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110685

Why not convert the dates to Date objects?

Code

require 'date'

regex = /\s(\w{3},\s\d{2}\s\w{3}\s\d{4}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\+00:00)/
s = str.gsub(regex, " Date.parse('\\1')")

and then

arr = eval(s)

to create an array from the string s. Notice that the regex ends with '00:00'.

Demo

str = "[[5473, 992, 'smth', Tue, 25 Mar 2014 05:08:12 UTC +00:00, Fri, 07 Mar 2014 22:55:42 UTC +00:00],
  [5473, 993, 'smth', Tue, 25 Mar 2014 14:38:05 UTC +00:00, Fri, 07 Mar 2014 22:57:33 UTC +00:00],
  [6084, 994, 'smth', Mon, 24 Mar 2014 23:37:37 UTC +00:00, Mon, 24 Mar 2014 23:37:37 UTC +00:00],
  [6084, 995, 'smth', nil, nil],
  [6084, 996, 'smth', nil, nil],
  [6084, 997, 'smth', nil, nil],
  [6084, 998, 'smth', nil, nil]]"

require 'awesome_print'
ap eval(str.gsub(regex, " Date.parse('\\1')"))
[
    [0] [
        [0] 5473,
        [1] 992,
        [2] "smth",
        [3] #<Date: 2014-03-25 ((2456742j,0s,0n),+0s,2299161j)>,
        [4] #<Date: 2014-03-07 ((2456724j,0s,0n),+0s,2299161j)>
    ],
    [1] [
        [0] 5473,
        [1] 993,
        [2] "smth",
        [3] #<Date: 2014-03-25 ((2456742j,0s,0n),+0s,2299161j)>,
        [4] #<Date: 2014-03-07 ((2456724j,0s,0n),+0s,2299161j)>
    ],
    [2] [
        [0] 6084,
        [1] 994,
        [2] "smth",
        [3] #<Date: 2014-03-24 ((2456741j,0s,0n),+0s,2299161j)>,
        [4] #<Date: 2014-03-24 ((2456741j,0s,0n),+0s,2299161j)>
    ],
    [3] [
        [0] 6084,
        [1] 995,
        [2] "smth",
        [3] nil,
        [4] nil
    ],
    [4] [
        [0] 6084,
        [1] 996,
        [2] "smth",
        [3] nil,
        [4] nil
    ],
    [5] [
        [0] 6084,
        [1] 997,
        [2] "smth",
        [3] nil,
        [4] nil
    ],
    [6] [
        [0] 6084,
        [1] 998,
        [2] "smth",
        [3] nil,
        [4] nil
    ]
]

Upvotes: 1

Sabuj Hassan
Sabuj Hassan

Reputation: 39365

Your two regex has only one difference, the last character is , or ]. So joined them in character class using [,\]]. And use it in your ruby gsub() like this way:

input = input.gsub(/(\s)(\w{3},\s\d{2}\s\w{3}\s\d{4}\s\d{2}:\d{2}:\d{2}\s\w{3}\s\+00:00)([,\]])/, " '\\2'\\3")

I have captured your date into group two \\2 and captured , or ] in group three \\3.

Capturing the group 1 wasn't necessary, but I didn't remove it. If you remove the capturing, then the grouping will be shifted from \\2 to \\1 and \\3 to \\2 in above code.

Upvotes: 2

Related Questions