Removing whitespace and rewriting comments, using regex searches

This article was contributed by Chad Loder.

Here are two very short macros that illustrate the regular expession find and replace features available both from the GUI and within the macro environment.

The first macro removes all trailing whitespace from all lines in the file. A naive implementation would loop over each line in the file, call RTrim() on the line, and then rewrite it. This implementation uses regex search/replace to accomplish the same task in a fraction of the time. It also lets you Undo in a single step.

The regular expression used is:

"\:b+\($\)" 

Reading left to right, this expession means find a:

  • whitespace char, "\:b",
  • actually one or more occurences of it, "+", followed by:
  • start a grouping, "\("
  • end of line, "$"
  • end grouping, "\)"

or in other words, find (one or more occurences of a whitespace char) followed immediately by and end of line.

And the replace value (the second argument to ActiveDocument.Selection.ReplaceText) is also special:

"\1" 

which means replace the found pattern with everything inside the first grouping. Note that the only thing in the grouping is the end of line pattern, so this means that we replace the entire pattern (whitespace + end of line) with just the end of line.


Sub RemoveTrailingWhitespace()
'DESCRIPTION: Remove all trailing whitespace from the document
 Dim curCol, curLine
 '-- save position
 curCol = ActiveDocument.Selection.CurrentColumn
 curLine = ActiveDocument.Selection.CurrentLine

 '-- replace all the trailing whitespace
 ActiveDocument.Selection.SelectAll
 ActiveDocument.Selection.ReplaceText "\:b+\($\)", "\1", dsMatchRegExp

 '-- restore position
 ActiveDocument.Selection.MoveTo curLine, curCol

End Sub

Here is another macro to illustrate the same concept. This macro replaces all single-line comments of the type

/* this is a comment */ 

with

// this is a comment

Note some important things about this regular expression.

First of all, the * (asterisk) character is a special character in regular expressions, so it has to be escaped by putting a \ (backslash) before it. Also, there are two groupings defined. The first grouping is all the text between the "/*" and the "*/", minus leading and trailing whitespace. The second grouping is the end of line.

Also, it is important to note that since a // comment makes the entire remainder of the line part of the comment, we have to be careful not to replace things like this:

for (int i = 1 /* start at second element */ ; i < n; i++) 

with the obviously incorrect:

for (int i = 1 // start at second element ; i < n; i++) 

so we make sure that the comment must have only whitespace between the ending */ and the end of the line. That is represented by the

"\:b*" 

before the end of line grouping. This says zero or more whitespace characters.



Sub ConvertStarComments()
'DESCRIPTION: Converts single-line star comments To single line slash
comments.

 Dim curCol, curLine
 '-- save position
 curCol = ActiveDocument.Selection.CurrentColumn
 curLine = ActiveDocument.Selection.CurrentLine

 '-- replace all the single-line star comments
 ActiveDocument.Selection.SelectAll
 ActiveDocument.Selection.ReplaceText "/\*\(.+\)\:b*\*/\:b*\($\)",
"//\1\2", dsMatchRegExp

 '-- restore position
 ActiveDocument.Selection.MoveTo curLine, curCol

End Sub



Comments

  • Slight change for VC7

    Posted by Legacy on 01/28/2003 12:00am

    Originally posted by: Doode

    Thanks for the great macro, I use this all the time in VC6. With a slight change, it also works in VC7.

    Sub RemoveTrailingWhitespace()
    'DESCRIPTION: Remove all trailing whitespace from the document
    Dim curCol, curLine
    '-- save position
    curCol = ActiveDocument.Selection.CurrentColumn
    curLine = ActiveDocument.Selection.CurrentLine
    '-- replace all the trailing whitespace
    Dim Doc As TextDocument = ActiveDocument.Object("TextDocument")
    Doc.ReplacePattern("[ \t]+$", "", vsFindOptions.vsFindOptionsRegularExpression)
    '-- restore position
    ActiveDocument.Selection.MoveTo(curLine, curCol)
    End Sub

    Reply
  • ROCKIN!

    Posted by Legacy on 06/21/2002 12:00am

    Originally posted by: Kevin Fleming

    Thanks for the Macro! I don't know why it took MS so long to include macros or why this one isn't a stock menu item.

    Reply
  • http://www.gotime.com/

    Posted by Legacy on 09/15/1999 12:00am

    Originally posted by: Paul Giglio

    The regex search string "\:b+\($\)" can be simplified to "\:b+$" with a corresponding empty replace string

    You don't need to group the end of line in the search string or specify it as the replacement string because VC won't let you kill them (as much as I wish it would)

    Thanks though- I've been using " +$" forever and missing any trailing tab characters the whole time

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Companies undertaking an IT project need to find the right balance between cost and functionality. It's important to start by determining whether to build a solution from scratch, buy an out-of-the-box solution, or a combination of both. In reality, most projects will require some system tailoring to meet business requirements. Decision-makers must understand how much software development is enough and craft a detailed implementation plan to ensure the project's success. This white paper examines the different …

  • On-demand Event Event Date: February 12, 2015 The evolution of systems engineering with the SysML modeling language has resulted in improved requirements specification, better architectural definition, and better hand-off to downstream engineering. Agile methods have proven successful in the software domain, but how can these methods be applied to systems engineering? Check out this webcast and join Bruce Powel Douglass, author of Real-Time Agility, as he discusses how agile methods have had a tremendous …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date