ShowUsYour<Blog>

Irregular expressions regularly

Regex Reminders [1] - Replacement Operations

A common application for regular expressions is to find and replace strings within a body of text. These operations range from something as simple as finding some text and removing it to locating and re-writing Hmtl tags. Let's take a quick look at the signatures of the .NET Regular Expression Replace overloads.

[VB]
    Instance
    --------
    Replace( ByVal input As String, ByVal replacement As String ) As String
    Replace( ByVal input As String, ByVal replacement As String, int count ) As String
    Replace( ByVal input As String, ByVal replacement As String, int count, int startat ) As String
    Replace( ByVal input As String, ByVal evaluator As MatchEvaluator ) As String
    Replace( ByVal input As String, ByVal evaluator As MatchEvaluator, ByVal count As Integer ) As String
    Replace( ByVal input As String, ByVal evaluator As MatchEvaluator, , ByVal count As Integer, ByVal startat As Integer ) As String

    Shared
    ------
    Replace( ByVal input As String, ByVal pattern As String, ByVal replacement As String ) As String
    Replace( ByVal input As String, ByVal pattern As String, ByVal replacement As String, ByVal options As RegexOptions ) As String
    Replace( ByVal input As String, ByVal pattern As String, ByVal evaluator As MatchEvaluator ) As String
    Replace( ByVal input As String, ByVal pattern As String, ByVal evaluator As MatchEvaluator, ByVal options As RegexOptions ) As String
[C#]
    instance
    --------
    string Replace( string input, string replacement )
    string Replace( string input, string replacement, int count )
    string Replace( string input, string replacement, int count, int startat )
    string Replace( string input, MatchEvaluator evaluator )
    string Replace( string input, MatchEvaluator evaluator, int count )
    string Replace( string input, MatchEvaluator evaluator, int count, int startat )

    static
    ------
    string Replace( string input, string pattern, string replacement )
    string Replace( string input, string pattern, string replacement, RegexOptions options )
    string Replace( string input, string pattern, MatchEvaluator evaluator  )
    string Replace( string input, string pattern, MatchEvaluator evaluator, RegexOptions options )
Msdn documentation

So, as you can see, there are instance and static (Shared) methods that are available to call when performing replacement operations. The most significant differences between the options are that you can either use a static string or a MatchEvaluator for the replacement argument. You would use a MatchEvaluator when you need to perform additional operations on the matched item - which we'll look at in a moment.

Simple Replacement - straight replace

A straight replacement is useful when you want look for patterns of text and simply replace them with another string (perhaps a zero length string). For example, you might want to find specific words and CAPITALIZE them or replace them with another word, or, just plain-old remove them. Here are some examples of simple, straight replacements:

Find a word and Capitalize it (using an instance method):

    [VB]

Dim source As String = "This is a body of text"
Dim find As String = "body"

Dim  re As New Regex( find, RegexOptions.IgnoreCase )
Dim result As String = "Result: " & re.Replace( source, find.ToUpper() )
    [C#]

string source = @"This is a body of text" ;
string find = "body" ;

Regex re = new Regex( find, RegexOptions.IgnoreCase ) ;
string result = "Result: " + re.Replace( source, find.ToUpper() ) ;
 

Trim leading and trailing whitespace (using a static method):

   [VB]
   
Dim source As String = "           foo                 "
Dim find As String = "(^\s+)|(\s+$)"
Dim result As String = "Result: " & Regex.Replace( source, find, "", RegexOptions.IgnoreCase )
 
    [C#]

string source = "           foo                 " ;
string find = @"(^\s+)|(\s+$)" ;
string result = "Result: " + Regex.Replace( source, find, "", RegexOptions.IgnoreCase )

Simple Replacement - referring to captured items

Another common use of Replace involves referring to the captured groups using the special $n or ${groupName} notation, for example:

Swap names around (using ordinal notation):

    [VB]

Dim source As String = String.Format("Mr. Darren Neimke{0}Mr. John Doe{0}Ms. Jane Doe", Environment.NewLine )
Dim find As String = "(\w+\.)\s+(\b\w+\b)\s+(\b\w+\b)"
Dim result As String = Regex.Replace( source, find, "$3, $1 $2" )
    [C#]

string source = String.Format("Mr. Darren Neimke{0}Mr. John Doe{0}Ms. Jane Doe", Environment.NewLine ) ;
string find = @"(\w+\.)\s+(\b\w+\b)\s+(\b\w+\b)" ;
string result = "Result: " + Regex.Replace( source, find, @"$3, $1 $2" ) ;

Format .com urls into hyperlinks (using named groups notation):

    [VB]
 
Dim source As String = "http://www.regexlib.com"
Dim find As String = "(?'Url'http\:\/\/www\.\w+\.com)"
Dim result As String = "Result: " & Regex.Replace( source, find, "<a href=""${url}"">${Url}</a>" )
    [C#]

string source = @"http://www.regexlib.com" ;
string find = @"(?'Url'http\:\/\/www\.\w+\.com)" ;
string result = "Result: " + Regex.Replace( source, find, @"<a href=""${url}"">${Url}</a>" ) ;

Simple Replacement - limiting the scope of replacement

You can use the overloaded instance method that takes a startat position argument to direct the regex to miss a section and only match within a given section of text:

Emboldens the word "blah" but only when found in the body of the document:

    [VB]
    
Dim source As String = "<html><head><title>blah</title></head><body>blah</body></html>"
Dim find As String = "(?'theWord'blah)"
Dim  re As New Regex( find, RegexOptions.IgnoreCase )
Dim result As String = "Result: " & re.Replace( source, "<b>${theWord}</b>", 9999, source.IndexOf("<body>") )
    [C#]

string source = @"     <html>
    <head>
        <title>blah</title>
    </head>
    <body>
        blah
    </body>
</html>" ;
string find = @"(?'theWord'blah)" ;

Regex re = new Regex( find, RegexOptions.IgnoreCase ) ;
string result = "Result: " + re.Replace( source, @"<b>${theWord}</b>", 9999, source.IndexOf("<body>") ) ;

MatchEvaluator - using a pointer as a replacement argument.

By using an overload that takse a MatchEvaluator for the replacement argument you can point to a delegate method to dynamically build the replace string. This is especially useful if you need to perform more complicated logic on the Match'ed text before inserting its replacement. Each match in the replace operation is handed off to the method that you define for your MatchEvaluator and, that method can do whatever it likes to the match and simply return a string that is then used as the replacement value. Here's an example using a MatchEvaluator that emboldens the word "foo" but only when NOT found as part of ANCHORS:

Match "foo" not in anchors using MatchEvaluator

    [VB]

Dim source As String = "<a >foo</a>foo"
Dim find As String = "(?'Url'<a [^>]*>.*?</a>)|(?'theWord'foo)"
Dim  re As New Regex( find, RegexOptions.IgnoreCase )

' use a MatchEvaluator with a pointer to the delegate method
Dim result As String = re.Replace( source, New MatchEvaluator( AddressOf FormatLinkBits ) )


' Delegate method
Private Function FormatLinkBits( ByVal m As Match ) As String
    If m.Groups("theWord").Success Then
        Dim theWord As String =  m.Groups("theWord").Value
        Return "<b>" & theWord & "</b>"
    Else 
        Return m.Value
    End If
End Function
    [C#]

string source = sourceTextBox.Text ;
Regex re = new Regex( @"(?'Url'<a [^>]*>.*?</a>)|(?'theWord'foo)" ) ;

// use a MatchEvaluator with a pointer to the delegate method
string result = re.Replace( source, new MatchEvaluator( FormatLinkBits ) ) ;


// delegate method
private string FormatLinkBits( Match m )
{
    if( m.Groups["theWord"].Success ) 
    {
        string theWord = m.Groups["theWord"].Value ;
        return "<b>" + theWord + "</b>" ;
    }
    else
        return m.Value ;
}

Here's another example that filters bad words and replaces them with censored text:

    [VB]

Dim source As String = "poo and browner are swearing expressions!"
Dim find As String = "(shit|poo|crap|turd|browner)"
Dim  re As New Regex( find, RegexOptions.IgnoreCase )

' use a MatchEvaluator with a pointer to the delegate method
Dim result As String = re.Replace( source, New MatchEvaluator( AddressOf FormatSwearWords ) )    


' delegate method
Private Function FormatSwearWords( ByVal m As Match ) As String
    Dim l As Integer = m.Value.Length
    Return m.Value.Substring(0, 2) & new String("#"c, l - 2)
End Function
    [C#]
  
string source = "poo and browner are swearing expressions!" ;
Regex re = new Regex( "shit|poo|crap|turd|browner" ) ;

// use a MatchEvaluator with a pointer to the delegate method
string result = re.Replace( source, new MatchEvaluator( FormatSwearWords ) ) ;

private string FormatSwearWords( Match m )
{
    int len = m.Value.Length ;
    return m.Value.Substring(0, 2) + new String('#', len - 2) ;
}
Posted: Sep 26 2003, 09:50 AM by digory | with 51 comment(s)
Filed under: , ,

Comments

TrackBack said:

# September 26, 2003 10:11 AM

TrackBack said:

# September 27, 2003 8:10 AM

Du said:

I really like this article .. however it would be much nicer if you post the result after the regex is performed

thanks
# January 15, 2004 11:35 PM

Darren Neimke said:

Agreed, thanks for the feedback. I'll see what I can do ;-)
# January 15, 2004 11:41 PM

mesh said:

how to find out the word ending with @ using regular expression?

my email id: mesh49@indiatimes.com
# February 20, 2004 2:20 AM

funzione di sostituzione | hilpers said:

Pingback from  funzione di sostituzione | hilpers

# January 18, 2009 8:51 AM

Andy said:

Very nice -- thank you

# January 26, 2009 1:08 PM

Raizel said:

Sorry. The supreme irony of life is that hardly anyone gets out of it alive. Help me! Need information about: Breitling watch calgary. I found only this - <a href="www.mydaughtersdna.com/.../breitling-for-bentley-motor-multifunction-watch">breitling for bentley motor multifunction watch</a>. When you account to refer wood you absorb how normal and complete that time can be, but first if you stand to affect clients on the holder, breitling watches. Sound conditions of hci design fairly green, breitling watches. :mad: Thanks in advance. Raizel from Republic.

# March 21, 2010 11:26 PM

kikus said:

отличный пост, автор пиши ещё

# June 13, 2010 11:47 AM

kikus said:

может у кого нить есть ещё информация по этому поводу??

# June 13, 2010 11:59 AM

kikus said:

интеретсный блог почему только так мало читателей на нём

# June 13, 2010 3:43 PM

kikus said:

отлично сделано, интеретсно читать 98)

# June 13, 2010 3:53 PM

knock off coach purses now said:

Real, www.gravatar.com/knockoffcoachpursese All about knock off coach purses,  780248,

# March 8, 2011 9:35 PM

Only groping train said:

Incredible site!, www.gravatar.com/gropingtraine groping train,  rhtb,

# March 8, 2011 10:28 PM

Best knock off coach purses said:

I have the same., www.crunchyroll.com/.../knockoffcoachpursesi knock off coach purses,  :P,

# March 9, 2011 7:47 AM

coach purses said:

So where it to find?, www.crunchyroll.com/.../coachpursesi coach purses,  61037,

# March 9, 2011 8:13 AM

louis vuitton purse said:

Best Wishes!, www.gravatar.com/louisvuittonpurses louis vuitton purse,  jtjjc,

# March 9, 2011 1:00 PM

skimpy g string bikini now said:

I want to say thanks!, www.gravatar.com/skimpygstringbikinio Real skimpy g string bikini,  tfgnu,

# March 9, 2011 5:25 PM

purse handles information said:

Great, www.crunchyroll.com/.../pursehandlesi First purse handles,  aqi,

# March 9, 2011 10:00 PM

pantyhose photography said:

Your Site Is Great, www.crunchyroll.com/.../pantyhosephotographa pantyhose photography for you,  gmsgt,

# March 10, 2011 12:12 AM

airline discount student ticket for you said:

I like your work!, www.amcharts.com/.../profile.php Cheapest airline discount student ticket,  :-O,

# March 25, 2011 9:35 AM

tax records copake new york information said:

Best Wishes, www.amcharts.com/.../profile.php tax records copake new york information,  684873,

# March 26, 2011 4:34 AM

short skirt gallery price said:

Give somebody the  to a site about the, forums.naturalparenting.com.au/.../shortskirtgallery.html short skirt gallery,  =],

# April 15, 2011 8:38 AM

Discount groping train said:

Beautiful site, forums.naturalparenting.com.au/.../gropingtrain.html groping train discount,  >:-P,

# April 15, 2011 1:03 PM

diovan said:

# April 15, 2011 7:56 PM

holiday magazine recipes said:

Beautiful site, www.gravatar.com/holidaybakingrecipes Buy holiday baking recipes,  8-[[[,

# June 19, 2011 6:07 PM

All about easy healthy recipes said:

Best Wishes, www.gravatar.com/bakedstuffedchickeni baked stuffed chicken recipes online,  :-],

# June 20, 2011 4:13 AM

easy dessert recipes online said:

Your Site Is Great, www.gravatar.com/freshstrawberrydesse fresh strawberry dessert recipes price,  108163,

# June 20, 2011 5:06 AM

Best olive garden soup recipes said:

Real, www.gravatar.com/marthastewarti martha stewart tv show recipes,  97194,

# June 20, 2011 7:56 AM

Buy girls in bikinis on motorcycles wallpaper said:

So where it to find?, www.gravatar.com/homemadebikine Buy homemade bikini contest,  shxmq,

# June 20, 2011 6:17 PM

she wet her pants said:

Your Site Is Great!, www.gravatar.com/sprayfoaminsuk All about spray foam insulation,  165,

# June 20, 2011 9:59 PM

caught with pants down said:

Hi, www.gravatar.com/seethroughpanf All about see through pants,  590,

# June 20, 2011 10:11 PM

First pinoy short stories said:

Your Site Is Great, www.gravatar.com/pinoyshortstoo pinoy short stories,  73124,

# June 21, 2011 2:50 AM

gene simmons costume for you said:

Help me to find the, www.gravatar.com/genesimmonshallowees gene simmons halloween costumes discount,  02881,

# June 21, 2011 3:46 PM

what sign is a good match for a scorpio said:

So where it to find, www.gravatar.com/whatistheprecursoroo Buy what is the precursor of the internet,  8-(,

# June 22, 2011 5:08 PM

Cheap what is a taint said:

Best Wishes!, www.gravatar.com/whatisacomputerhoaxi First what is a computer hoax,  oxfg,

# June 22, 2011 5:58 PM

All about crazy names for msn said:

I want to say thanks!, www.gravatar.com/clevernamesforateams clever names for a team,  0328,

# June 22, 2011 7:48 PM

Cheapest congenital heart disease said:

Hi, www.gravatar.com/celiacdiseasesymptos celiac disease symptoms,  reblnw,

# June 22, 2011 8:13 PM

celebrity wardrobe malfunctions for you said:

Only, www.gravatar.com/britneyspearswardroi britney spears wardrobe malfunction price,  8O,

# June 23, 2011 1:52 AM

Cheap greek mythology family tree said:

can you do thi for me, www.gravatar.com/greekmythologyfamils Cheap greek mythology family tree,  :))),

# June 23, 2011 3:07 AM

best family ski resorts for you said:

I want to say thanks!, www.gravatar.com/familynaturistalbums All about family naturist albums,  pdod,

# June 23, 2011 3:21 AM

cool skateboards said:

I like it so much, www.gravatar.com/buildyourownskateboo build your own skateboard,  63788,

# June 23, 2011 4:32 AM

is the post office open on columbus day said:

Best Wishes, www.gravatar.com/theofficecasto the office cast,  %-OO,

# June 23, 2011 5:47 PM

Buy holiday gift ideas said:

I like it so much, www.gravatar.com/holidaygiftidease Buy holiday gift ideas,  714936,

# June 23, 2011 9:31 PM

top holiday products said:

Your Site Is Great, www.gravatar.com/topholidayproductss top holiday products now,  8-OO,

# June 23, 2011 10:24 PM

Real good girls gone bad said:

Give somebody the  to a site about the, www.gravatar.com/goodgiftsforvalentis good gifts for valentines,  :-P,

# June 23, 2011 11:51 PM

Pupeevetlylit said:

Доброго времени суток,  

Хочу представить вам новый лабаз курительных смесей

сайт магазина http://spice-family.ru  

3г микса Moderate - 1,500 р. + доставка (ems, pony set)  

Сообразно вопросам опта вносить оазисами в скайп - FomaX2

# September 2, 2011 10:37 PM

Pupeevetlylit said:

Доброго времени суток,  

Хочу представить вам новый лабаз курительных смесей

сайт магазина http://spice-family.ru  

3г микса Moderate - 1,500 р. + доставка (ems, pony intimate)  

Сообразно вопросам опта писать отдельно в скайп - FomaX2

# September 2, 2011 10:46 PM

ReageasencyuI said:

Что для Вас Юмор?    

<a href=http://xn--c1aeb8eua.xn--p1ai/>мелодии приколы бесплатно приколы</a>

# January 31, 2012 6:20 AM

ReageasencyuI said:

Насчет тонкого юмора поняли... А бывает толстый юмор?    

<a href=http://xn--c1aeb8eua.xn--p1ai/>бесплатные аниме картинки 128 97</a>

# February 2, 2012 7:52 AM

ReageasencyuI said:

Насчет тонкого юмора поняли... А бывает толстый юмор?    

<a href=http://xn--c1aeb8eua.xn--p1ai/>sms приколы версии для печати</a>

# February 2, 2012 9:12 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)