Click here to Skip to main content
Click here to Skip to main content

Replace text using tagged expressions

By , 2 Feb 2006
 

Introduction

Visual Studio has a very powerful search and replace feature, which is the "tagged expression". You can search and replace using regular expressions, keeping groups of content intact. This can be useful in stuff like refactoring or simply reformatting code.

The basics

A tagged expression is used to identify a piece of text so it can be used in the replacement. You identify a tagged expression with "{" and "}". You can use as many of those as you want.

If you enter the following in the replace dialog:

Find what:

{ content }

Replace with:

\1

You are replacing the group containing "content" with the same.

The following entry will replace the selection with the same:

Find what:

{.*}

Replace with:

\1

Just to be clear, a picture of the dialog:

So what?

OK, I admit, so far it doesn't look very useful. However, from this starting point, you can use any expression to split up text in parts and reassemble them.

Here's a hopefully more interesting example of what you can do:

Given below is an SQL connection string property value after dragging a data source in the designer:

workstation id=LEBOWSKI;packet size=4096;
   user id=sa;data source=LEBOWSKI;
   persist security info=True;
   initial catalog=TheInternet;password=protected

If I replace:

Find what:

{[^=]*}={[^;]*};

Replace with:

options.Add("\1", "\2");\n

You'll get the following:

options.Add("workstation id", "LEBOWSKI");
options.Add("packet size", "4096");
options.Add("user id", "sa");
options.Add("data source", "LEBOWSKI");
options.Add("persist security info", "True");
options.Add("initial catalog", "TheInternet");
options.Add("password", "protected");

Note: "[^=]" means any character except "=", and "*" means as many as there are.

Final words

This may not be a sample you will use yourself, but I hope to have shown you the power of what you can do. And hopefully you'll start using it yourself.

For an overview of the expression syntax, click on the Help button in the Replace dialog. Thanks for reading!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Michel.Smits
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalhimembermrmubi24 Feb '06 - 2:01 
i want to search for all numbers in code having 3 digits for example 123,789,785 etc...
what will be the search regular expression...
 
 Mubi 

GeneralRe: himemberxyzzer2 Mar '06 - 23:13 
[0-9][0-9][0-9]
GeneralThanks and Regex commentmemberlarbs15 Feb '06 - 5:20 
Thanks for pointing this out. I am pretty familiar Regex but did not realize you could do this with vstudio. I would take this over Macros any day of the week.... It is odd how few folks use regex condering how powerful it is for BS day to day reformatting etc.
 
Also, not that this was the point of your article at all, but this regex
{.#}={.#};
(ie minimal matching)
is probably a lot less expensive than the [^=]*.... version
Not important in a quick find and replace, but could make a big difference in an app.
GeneralRe: Thanks and Regex commentmembermsmits19 Feb '06 - 22:47 
Good point (minimal match) that I should have put in.
Thanks for the comment!
GeneralI prefer macrosmemberxyzzer499 Feb '06 - 0:18 
In situations as in that sample and especially when converting a table or list of values into a sequence of assignments, calls, declarations etc - I prefer to use macros. It is easier to record and play a macro that does something, than write a regular expression for the same thing. Sometimes only one of the two options is possible so I value them both highly, as they enable to really streamline code generation. Aside from that - it is not something they teach at those programming courses at the university (at least they did not on mine) - so it looks so pro... :]
 
In this example, using VS2005 I would record the macro as following...
 
Piece of initial text
workstation id=LEBOWSKI;packet size=4096;user id=sa;data source=LEBOWSKI;persist security info=True;initial catalog=TheInternet;password=protected
 
The sequence of actions to record the macro:
0. Put the cursor at the beginning of the text
1. Ctrl+Shift+R (starts recording)
2. Type: options.Add("
3. Open a find window (Ctrl+F) and look for character '='
4. Type: ", "
5. Press: Ctrl+Right Arrow (jumps to the end of the word)
6. Type: ");
7. Press Enter for new line
8. Press Delete to remove the semicolon
9. Ctrl+Shift+R to end recording
 
Now while holding Ctrl+Shift press P a couple of times and you've got your output text with sequence of function calls.
You can even see the actual VB code (Alt+F11) for the macro and edit it if you want to get something more custom, but that probably does not happen very often - at least I have not used that yet.
The key settings for macros might be different in your environment, so you might need to check them or set them up.
 
Using a similiar technique I often generate properties in C# - just starting with a list of a few dozen words - you just have to change one word into a property, remembering to start with the caret at the beginning of the first word and ending with the caret at the beginning of the second word and using clipboard to put the word in the source of the property a few times.
 
That is most useful when you want to read some data from a file - e.g. an XML one. You get a list of tag names in your source code, record and use one macro to generate the properties with the same names as XML element names to store the values and then another macro to retrieve values from the XML file and assign them to these properties.
You can create hundreds of lines of tedious code in a matter of seconds. Real robust.
 
-- modified at 6:25 Thursday 9th February, 2006
The reason why I prefer macros when possible is that you do not have to remember all the special characters and the syntax used in search and replace strings, which is a problem if you only need them once in a while - especially, that they differ among various editors - they even differ between VS and .NET System.Text.RegularExpressions namespace.
 
-- modified at 6:38 Thursday 9th February, 2006
The macro code sample below can be used to transform a list of names separated by a new line only into a sequence of properties of a C# class, nicely enclosed in #region outlining tag. Just open the macro editor and replace the code of the RecordingModule with the one below.
 
Option Strict Off
Option Explicit Off
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
 
Public Module RecordingModule
 

Sub TemporaryMacro()
DTE.ActiveDocument.Selection.EndOfLine(True)
DTE.ActiveDocument.Selection.Copy()
DTE.ActiveDocument.Selection.StartOfLine(VsStartOfLineOptions.VsStartOfLineOptionsFirstColumn)
DTE.ActiveDocument.Selection.Text = "#region "
DTE.ActiveDocument.Selection.StartOfLine(VsStartOfLineOptions.VsStartOfLineOptionsFirstText)
DTE.ActiveDocument.Selection.Indent(2)
DTE.ActiveDocument.Selection.EndOfLine()
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "#endregion"
DTE.ActiveDocument.Selection.StartOfLine(VsStartOfLineOptions.VsStartOfLineOptionsFirstText)
DTE.ActiveDocument.Selection.Indent(2)
DTE.ActiveDocument.Selection.LineUp()
DTE.ActiveDocument.Selection.EndOfLine()
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "private string m_"
DTE.ActiveDocument.Selection.Paste()
DTE.ActiveDocument.Selection.Text = ";"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "public string "
DTE.ActiveDocument.Selection.Paste()
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "{"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "get"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "{"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "return m_"
DTE.ActiveDocument.Selection.Paste()
DTE.ActiveDocument.Selection.Text = ";"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "}"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "set"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "{"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "m_"
DTE.ActiveDocument.Selection.Paste()
DTE.ActiveDocument.Selection.Text = " = value;"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "}"
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.Text = "}"
DTE.ActiveDocument.Selection.LineDown()
DTE.ExecuteCommand("Edit.ToggleOutliningExpansion")
DTE.ActiveDocument.Selection.LineDown()
DTE.ActiveDocument.Selection.StartOfLine(VsStartOfLineOptions.VsStartOfLineOptionsFirstText)
DTE.ActiveDocument.Selection.NewLine()
DTE.ActiveDocument.Selection.DeleteLeft(2)
End Sub
End Module
 
-- modified at 6:47 Thursday 9th February, 2006
And I hope that is the last time I have modified this post. Big Grin | :-D
GeneralRe: I prefer macrosmembermsmits9 Feb '06 - 1:56 
This is a good alternative for most situations... both methods do have their unique advantages.
As you say regular expressions do not have an easy to learn (or remember) syntax unless you use them regularly. Macros are easy and more known since they exist in any Office app.
 
I guess it comes down to preference, which basically covers your subject title Wink | ;-)
 
Thanks for your post.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 2 Feb 2006
Article Copyright 2006 by Michel.Smits
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid