dermoth
dermoth

Reputation: 35

Ruby regexp throws invalid backref number/name error

My current code is intended to go through an enormous .csv file and reformat certain dates to an SQL Datetime friendly format. They are currently DDMMYYYY, I want them as YYYYMMDD, and this is the approach I've taken (lifted from a different SO question):

CSV.foreach('file.csv') do |x|
if x[0] == "1"
    x.gsub(/([0-9]{2})-+([0-9]{2})-+([0-9]{4})/,/\3-\2-\1/)

else
end

This throws the error "invalid backref number/name".

Docs tell me I can avoid this by defining the groups with ?<name> and backreferencing them with \k<name>, but all my attempts to do so have ended in failure. Could someone show me how it's supposed to look, or provide an alternate solution?

Upvotes: 1

Views: 1309

Answers (5)

Stewart
Stewart

Reputation: 3161

I think it's worth adding that while the above answers are correct they don't address the error that the OP was getting. This error is not an issue with the second parameter being a regular expression. In fact in the above case ruby never actually calls the gsub method as the regular expression in the second parameter won't parse. A backslash followed by any number will cause this error. It's an invalid regular expression.

Upvotes: 3

Patrick Oscity
Patrick Oscity

Reputation: 54714

I'd go with Date::strptime and Date#strftime:

dates = %w[12122012 10121012 12032013]
#=> ["12122012", "10121012", "12032013"]

dates.each do |date_str|
  date = Date.strptime(date_str, '%d%m%Y')
  puts date.strftime('%Y %m %d')
end

# 2012 12 12
# 1012 12 10
# 2013 03 12

Upvotes: 0

Justin Ko
Justin Ko

Reputation: 46846

The second parameter for the gsub should be a string, not a regex (see the docs).

Do:

x.gsub(/([0-9]{2})-+([0-9]{2})-+([0-9]{4})/,'\3-\2-\1')

Note that the second parameter uses 'replacement string' instead of /replacement string/.

Upvotes: 4

steenslag
steenslag

Reputation: 80085

No regex:

str = "DDMMYYYY"
p new_str = str[4..7] << str[2..3] << str[0..1]
#=> "YYYYMMDD"

Upvotes: 5

theglauber
theglauber

Reputation: 29645

Use ' to delimit your second gsub parameter (the replacement string), instead of /

Upvotes: 0

Related Questions