May 23, 2024

Vim and regular expressions

It is certainly possible to use Vim effectively and never get tangled up with regular expressions. Where regular expressions can be really useful is in fancy use of the "s" command in command line (colon) mode. Also in searches on rare occasions.

Here is an example. I have a file that has hundreds of lines that look like this:

00018620:       00000205        andeq   r0, r0, r5, lsl #4
00018624:       00000085        andeq   r0, r0, r5, lsl #1
00018628:       00000000        andeq   r0, r0, r0
0001862c:       00000002        andeq   r0, r0, r2
I want to keep just the first two columns and trim off the rest.

How many kinds of regular expressions are there?

There are at least 3 that I commonly run across. We have grep, perl, and vim to this way of thinking. Maybe more if I dig deeper, but just knowing that there are different flavors will have you on your guard. The important thing is to not drag your knowledge of grep or perl into vim, otherwise unpleasant surprises will trip you up.

Vim regex basics

A harmless way to play around is to use the "/" to do searches. Use :h pattern or :h regex to start looking at the online vim help. I found :h usr_27 to be somewhat helpful, but it rapidly dives deep into arcane topics and does not give an introduction.
[abc] is any one of the 3 characters a, b, or c
\s -- represents any whitespace character
\d -- represents any decimal digit
\w -- represents any word character, i.e. [0-9a-zA-Z]
\v -- at the start says "very magic mode on"
. -- the "dot" matches any character
* -- says zero or more of the previous character
+ -- says one or more of the previous character
The idea with very magic mode is that you can use special characters without putting a backslash in front to make them have their special power.

There is a lot more and I won't try to replicate all of the excellent material that already exists here.

Back to my problem

Given the above to jolt my memory, I worked this up for my task. Note that without the \v indicator I would have needed a multitude of backslash characters in my pattern.

21528,21543g/\v^\w+:/s/\v(^\w+:\s+\w+).*/\1
'a,.g/\v^\w+:/s/\v(^\w+:\s+\w+).*/\1

This worked perfectly. Note that I actually used the second line where I reference a mark I placed at the start of the region I wanted to process, and the current line to end the region.

What could be simpler than this! Ha ha.
The choice with these sorts of things is whether you want to do a bunch of error prone repetitive line by line chopping, or spend the time to solve a puzzle like this. It is certainly more interesting and fun to solve the puzzle, and in this case with perhaps 1000 lines, it saved time as well. Not only that, you are that much smarter for the next time something of the sort comes along.


Have any comments? Questions? Drop me a line!

Tom's vim pages / tom@mmto.org