Find And Replace With Regular Expressions In Vim / ViEmu


Here’s another entry in my how-i-saved-a-few-hundred-keystrokes blog posts on using Vim / ViEmu with Visual Studio.

 

The Code That Needs To Change

I’ve got a data access method that is mapping around 50 fields into an object from a data table. I’m in the process of changing the code from raw reads off the data table’s indexer with Convert.To… statements into a data reader with my type safe data reader being used. There are 9 lines of code that read and convert to an Int32 and around as many for DateTime, Decimal, String and a few others.

Here’s the Int32 portion of the code, to make it easier to see what’s going on:

   1: public Record MapOneFrom(IDataReader dataReader)

   2: {

   3:     var dr = new TypeSafeDataReader(dataReader);

   4:  

   5:     var record = new Record();

   6:  

   7:     record.Id = Convert.ToInt32(dataRow["Id"]);

   8:     record.Action = _actionRepository.GetById(Convert.ToInt32(dataRow["ActionId"]));

   9:     record.User = _userRepository.GetById(Convert.ToInt32(dataRow["UserId"]));

  10:     record.Location = _locationRepository.GetById(Convert.ToInt32(dataRow["LocationId"]));

  11:     record.OriginLocation = _locationRepository.GetById(Convert.ToInt32(dataRow["OriginLocationId"]));

  12:     record.BuildingId = Convert.ToInt32(dataRow["BuildingId"]);

  13:     record.PersonId = Convert.ToInt32(dataRow["PersonId"]);

  14:     record.UseStateIdForDelivers = Convert.ToInt32(dataRow["UseStateIdForDelivers"]);

  15:     record.UseStateIdForReturns = Convert.ToInt32(dataRow["UseStateIdForReturns"]);

  16:  

  17:     //insert a lot more reading / converting for DateTime, String, Decimal, etc.

  18:  

  19:     return record;

  20: }

</div> </div>

I want to change all of the code that reads:

   1: Convert.ToInt32(dataRow["some column name"])

</div> </div>

to:

   1: dr.GetInt32("some column name")

</div> </div>

without having to manually copy & paste, re-type the same thing, or adjust the column name in the quotes, as I would have done in the past.

 

The Regex Find And Replace

I’ve known about Vim / ViEmu’s ability to do regular expression find and replace for a while, so I figured this would be a good time to learn. I found some good instructions on using regular expressions with find and replace with Vim / ViEmu via Google and after some playing around with it to learn the differences in the regex syntax compared to what I’m used to in .NET, I was able to once again save myself a few hundred keystrokes in a scenario.

Here’s the find & replace that I issued to accomplish what I wanted for my Int32 conversion:

:%s/Convert.ToInt32(dataRow[(“.*”)])/dr.GetInt32(1)/g

I’ll leave it up to the reader to do the research on the syntax for find and replace, and regular expressions in vim. Anyone who has done regular expressions in .NET will immediately question the syntax of this expression, though… it took me about 15 minutes of trying to figure this out, honestly. But once I did figure it out, I was able to quickly and easily replace all of the code in question for my Int32 data reading. The result looks like this:

   1: public Record MapOneFrom(IDataReader dataReader)

   2: {

   3:     var dr = new TypeSafeDataReader(dataReader);

   4:  

   5:     var record = new Record();

   6:  

   7:     record.Id = dr.GetInt32("Id");

   8:     record.Action = _actionRepository.GetById(dr.GetInt32("ActionId"));

   9:     record.User = _userRepository.GetById(dr.GetInt32("UserId"));

  10:     record.Location = _locationRepository.GetById(dr.GetInt32("LocationId"));

  11:     record.OriginLocation = _locationRepository.GetById(dr.GetInt32("OriginLocationId"));

  12:     record.BuildingId = dr.GetInt32("BuildingId");

  13:     record.PersonId = dr.GetInt32("PersonId");

  14:     record.UseStateIdForDelivers = dr.GetInt32("UseStateIdForDelivers");

  15:     record.UseStateIdForReturns = dr.GetInt32("UseStateIdForReturns");

  16:  

  17:     //insert a lot more reading / converting for DateTime, String, Decimal, etc.

  18:  

  19:     return record;

  20: }

</div> </div>

Now repeat that same find and replace pattern, specifying String or DateTime or whatever else I need instead of Int32, and I’m good to go!

 

I’m Really Starting To Love ViEmu

I spend most of my vim-time in ViEmu… I haven’t used gVim or macVim very much (yet) but I’m learning pretty quickly while still having a safety net in Visual Studio. I’m also falling in love with ViEmu and the whole idea of Vim in general. Especially when I just found yet another way to save myself several hundred keystrokes – approximately 300+ keystrokes for each find and replace in this case, for a total of well over 1,200 keystrokes saved!

If you still haven’t tried out Vim or ViEmu yet, you owe it to yourself and your eventual-productivity-improvement to do so. It really is worth the hype.

Why I Write Automated Tests For My Code