Fun with VIM, regex, and PHP

Posted by jason on Oct. 14, 2011, 6:52 p.m.
Tags: php programming regex vim


I've been having a lot of fun with regular expressions and vim lately, specifically while programming in PHP. Here are a couple of real-world examples where I saved myself a lot of time and increased my vim+regex skills in the process.

These examples are simple: I just use "\w" to match letters, numbers, and underscores and put it between "\(" and "\)" so I can reference it later as "\1". Look at the examples if you don't know what I'm talking about.

Adding 'mysql_real_escape_string()' to a series of variables

Here is what I had:

$query = "
    INSERT INTO `table` (col1, col2, col3, col4)

Here is what I wanted:

$query = "
    INSERT INTO `table` (col1, col2, col3, col4)
        '" . mysql_real_escape_string($this->var1) . "',
        '" . mysql_real_escape_string($this->var2) . "',
        '" . mysql_real_escape_string($this->var3) . "',
        '" . mysql_real_escape_string($this->var4) . "'

Finally, here is the command I ran in vim to make these changes happen:

<from>,<to> s/\(\$this->\w\+\)/" \. mysql_real_escape_string(\1) \. "

Let's break down some of the key parts of the regular expression:

  • <from>,<to>: The range of line numbers to apply the changes to.
  • s/\(\$this->\w\+\): Search for "$this->".
  • /" \. mysql_real_escape_string(\1) \. ": Replace with " . mysql_real_escape_string($this->) . ".

Note that any matches found between \( and \) can be referred to later as \1, \2, etc. The number just increases as you go left to right.

This search and replace operation came in handy when I was dealing with a table that had over 20 columns.

Assigning variables to a class object

Here is a similar example. I had an associative array with a bunch of values that I wanted to assign to an object. The keys in the associative array had the same names are the member variables of my class object. So I just copy-pasted the following lines from my class declaration:

var $var1;
var $var2;
var $var3;

I wanted those lines to look like this:

$obj->var1 = $clean_vars['var1'];
$obj->var2 = $clean_vars['var2'];
$obj->var3 = $clean_vars['var3'];

Here is the vim command I needed to make it so:

<from>,<to> s/var \$\(\w\+\)/\$this->\1 = \$clean_vars\['\1'\]

This search and replace is quite similar to the last one: search for "var $<varname>" and replace with "$obj-><varname> = $clean_vars['<varname>'];".