Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

RegExp question 4

Status
Not open for further replies.

guitardave78

Programmer
Sep 5, 2001
1,294
GB
Is there a way to replace the 1st occurance, then loop to the second then third in a replace expression.

The reason is i want each match in a string to be highlighted differently

}...the bane of my life!
 
Nope ...

As I say, it's very obscure


Okey dokey. What happens with the RegExp object when you call the Replace method?

eg
myRegExp.Pattern=strSomePattern
strResult=myRegExp.Replace(strSource, SomeString)

Well, what happens is that for each string in StrResource that matches strPattern myRegExp runs its own private, internal ReplacerFunction which uses the contents of SomeString as a parameter. This is basically hidden from you, but in in essence what logically is happening might appear to be:

strResult=myRegExp.Replace(strSource, myRegExpPrivateReplacerFunction(SomeString))

But that isn't quite the case, since the second parameter to the Replace function is really a function template that is then serially used and applied against each match. RegExp automatically fills in all the parameters to that template for us, since they are derived from the pattern match that occurs. Normally we don't see those parameters at all, but they are:

PrivateReplacerFunction(matchedString [, subMatch1 [, ...]] , matchPos, source)

where

matchedString
The entire substring string that matched the regular expression or SomeString, if it is provided
subMatch1
The first captured submatch, if any
...
Additional captured submatches, if any (but there could be many ,depending on the .Pattern used)
matchPos
The position within the source string that the match was found
source
The entire source string being searched

Now PrivateReplacerFunction is a) something we don't have access to b) relatively simple (basically straight replacment with SomeString, or a minor amount of trickery involving submatches)

What we have done is write a replacement for the internal PrivateReplacerFunction (and the trick with the default method, whilst neat, is actually absolutely vital for this replacement technique to work because of how the regular expression object actually treats the second parameter od the Replace function)

So what we are doing when we make this call in the ROT13 example:

Text2.Text = re.Replace(Text1.Text, myReplacer)

is telling the regexp object that we want to use our MyReplacer object to supply the function template that is to be used against each match that is found. As described above the regexp object will fill in all the parameters for us. We use a ParamArray in the template because we have no idea how many parameters we are actually going to get, which means that if there are 'n' items in the ParamArray:

a(0) = matchedString

if 'n'>1 then
a(n-1) = MatchPos
a(n) = source

and if n>2, then
a(1) - a(n-2) = submatches


Here's an illustration of using some of those additional parameters that the regexp kindly fills in for us. To supplement the ROT13 code (which I described as 'poor' because it isn't the most elegant way to do the rotation) with the following we'll look at capitalising sentences. Add a new class (Class2) to the project we've alreay created for ROT13. Add (and be warned that these are examples only, so I'm not including error checking or tests to check how many parameters I'm actually getting):
Code:
[blue]Option Explicit

Public Function ReplacerFunction(ParamArray a()) As String
    ReplacerFunction = a(1) & UCase(a(2))
End Function[/blue]

Make this the default method of this class. Now add a command button to yur form, and drop in:
Code:
[blue]Private Sub Command1_Click()
    Dim myReplacer As Class2
    Dim re As RegExp
    
    Set myReplacer = New Class2
    Set re = New RegExp
    re.Global = True
    re.Pattern = "(^|""|[\.!\?]\s+)(\w{1})"
    MsgBox re.Replace("testing. testing. testing. wow! i think it works", myReplacer)
End Sub
[/blue]










 
(erm, my 'nope' was directed at BobRode's initial stab at what was going on here, but of copurse the response took long enough to write that all these extra posts got in ...)
 
Darn, strongm, you're making me work. If you're going to take the trouble to explain it in detail, I'm going to have to...hmm, what's the word...inculcate it. Yes, that's what I'm going to have to do. And on the 4th of July, too. (You know, "Riddance Day", I believe Punch magazine called it.) Glad I don't have a wife. Well, at least sometimes.

Seriously, this is very interesting stuff. Thanks for going to the trouble.

Regards,

Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top