CRS
CRS

Reputation: 75

Using VIM's regex to convert MM/DD/YYYY to proper date ("June 4, 1999") for end user consumption

Here are my parameters:

The challenge: make a regular expression to fix this quickly, on a per computer basis.

This is what I have (using #'s as delimiters):

%s#\([1-9]\|1[012]\)[- /.]\([1-9]\|[12][0-9]\|3[01]\)[- /.]\([19\|20]\d\d\)#UGLYPART \2, \3#g

The search part works correctly, as I get \2 and \3 in the correct place. I know the UGLYPART will use \1, and then some sort of evaluation like:

((\1)\=(1\|2\|3\|4\|5\|6\|7\|8\|9\|10\|11\|12)(January\|February\|March\|April\|May\|June\|July\|August\|September\|October\|November\|December)) 

Except that it will work.

Does anyone have any insight? I feel like I'm about 90% there. Or am I asking too much of Vim's regex?

Upvotes: 2

Views: 2351

Answers (2)

ZyX
ZyX

Reputation: 53644

Yes, you should use \=, but it is used in another fashion:

%s#\v([1-9]|1[012])[\- /.]([1-9]|[12][0-9]|3[01])[- /.]((19|20)\d\d)#\=strftime('%B', 28*24*60*60*submatch(1)).' '.submatch(2).', '.submatch(3)#g

Note: [] is a collection, thus [19\|20] you written here is treated as 1, 9, \, |, 2 or 0. You should use \(19\|20\). And use \v to avoid unneeded escapes.

Note 2: I do not want to write a list of months. You can see that 28th day of year is January, 28*2=56th is February, 28*3=84th is March and so on up to December, so you can use strftime() function and the fact that timestamp 0 (in seconds) is 1st January (not of the current year, but this does not matter). It will depend on locale though: in english locale strftime('%B', 28*24*60*60*1) will output “January”, but on my system it outputs “Январь”.

Note 3: \= must always be on the very first position in replacement string.

Upvotes: 4

gbulmer
gbulmer

Reputation: 4290

I think you can use vim in "line edit" (ex) mode, using -e. Then give it a file of edit commands.

Assume these commands are in date.ex:

g/\([0-9][0-9]*\)[./-]1[./-]\([012][0-9][0-9]*\)/s//January \1, \2/
g/\([0-9][0-9]*\)[./-]2[./-]\([012][0-9][0-9]*\)/s//February \1, \2/
g/\([0-9][0-9]*\)[./-]3[./-]\([012][0-9][0-9]*\)/s//March \1, \2/
... etc ...
w
q

then invoke vim as

vim -e -S date.ex foo

where foo is the file you want to edit. SO yoy can have a shell script to run this across all the files in a file system.

Upvotes: 1

Related Questions