Our internal custom tracing library was recently updated, and I’ve been working on doing some extensive search-and-replaces to incorporate the changes. At first, I thought I could use Visual Studio to quickly do the bulk of it with it’s handy Find and Replace in Files, even with it’s “bastardized syntax“. But I ran across a showstopper–Visual Studio’s regular expression engine is greedy by default (as are nearly all others), but it does not seem to include any way to force the engine to be lazy (or non-greedy). This seems like a pretty basic regex feature.
For example, one of the things that has been changed is the string formatting style. It went from the typical .NET format string using positional placeholders (”Critical error: {0}, Warning: {1}, Success: {2}”) to straight replacement (”Critical error: {}, Warning: {}, Success: {}”). A very simple search and replace should be able to take care of this. Using the Visual Studio syntax, it would look something like:
Find: {CustomTraceLibrary\.Trace.*}\{[0-9]+\}
Replace: \1{}
Using that expression (note I have a typo in my screenshot, as I didn’t escape the “.” between CustomTraceLibrary and Trace, but that’s irrelevant) I get this result:
It’s what I would expect, given that regular expressions are greedy. But the problem was that adding the typical “?” to indicate a non-greedy match simply tells me there are no matches (most likely indicating an invalid regular expression): “{CustomTraceLibrary\.Trace.*?}\{[0-9]+\}”. And, while I’m a decent “googler”, I couldn’t find anything that even addresses the topic. It’s certainly not mentioned on the Visual Studio Regular Expression MSDN reference.
So really, what I’m asking is whether anybody knows if I can tell a regular expression in Visual Studio to be lazy/non-greedy?
Update: A gracious anonymous commenter pointed out that I’m a moron. The answer was in plain sight on the MSDN reference, as well as in the Visual Studio IDE. “@” is the lazy version of “*”, and “#” is the lazy version of “+”. I feel quite dumb at the moment. Thanks anon!
Oh, and here’s some decent resources I found as I looked around:
Roy Osherove briefly covers what “greedy” means.
The aforementioned MSDN reference.
A forum post with lots of handy Regex links.
Jeff Atwood laments on Visual Studio’s Regex implementation (with an interesting comment by Neil Enns, a Lead Program Manager with Visual Studio).
Jon Galloway mentions using Find/Replace.



August 22, 2007 at 23:29
If you were to write “find and replace” basic/crystal “formula”. How would you do it. I am working in crystal reports and i want to set up about 130 find/replace for differennt abreviations.
For example:
if you find “REAMER” (anywhere in the assigned collumn) replace it with “RMR” AND
IF ………. AND
140 more of these.
NO case sensitive search but upper case replacment) !
THANKS,
branko22@gmail.com
August 22, 2007 at 23:29
Do you ever have one of those moments where you feel like a complete moron? No? Well I do!
Now is one of those times. Thank you for pointing that out! I can’t BELIEVE I missed that — I went back and looked and it’s even on the MSDN reference page. Geez.
I feel a little better, though, because the PowerShell script worked out better for me in the end (whew!).
Thanks again!!!!
August 22, 2007 at 23:29
Hi,
Based on the documentation in VS2005:
* and + are greedy, but
@ and # are their lazy equivalents
(I found these and more by clicking on the dropdown to the right of the text box and clicking on ‘Complete Character List’ )
Sounds like I found this too late for you though.
August 22, 2007 at 23:29
I had seen that, and other search/replace tools (I technically didn’t even need Visual Studio, I was just using the sledge hammer to pound in a tack
).
I ended up writing a PowerShell script, which worked out much better in the long run because I was able to automate much of the process (which involved several similar search/replaces, etc.)
Thanks!
August 22, 2007 at 23:29
If it were me, I’d download something like http://www.codeproject.com/csharp/SearcherAddIn.asp
And then be able to use the System.Text.RegularExpressions version which make sense to me since I use them so much.