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!
 
Syntax:
Replace(expression, find, replacewith[, start[, count[, compare]]])

If you found the match, just set the start parameter equal to the index of the previous match + 1.
 
mmm looks promising, from my thicko point of view, one more bit of help pweeeeeaaasssseeee!!!

this is the loop
Code:
For Each Match in Matches
  temp = RegularExpressionObject.replace(temp,"<span class='highlight'>"&tCase(Match.Value)&"</span>")
  i=i+1
Next
match has firstindex which is the index of the current match and match.value is what it matched on

the regular expression used to get the matches is
"\b"&search&"s?\b"

this is doing my nut!!!

}...the bane of my life!
 
Make sure RegularExpressionObject.Global = False

Otherwise the first iteration thru the for loop will replace all of them.

Otherwise see my posting in your other thread like this one.


Tracy Dryden

Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard. [dragon]
 
There's a very obscure (but rather powerful) trick you can play with regular expressions in VB that allows you to apply your own custom replacment/processing of each match as it is found in a single pass rather than having to get a Matches collection, and then looping throught the text again to do the replacements

If you're interested ...
 
Ok, here's a simple illustration of the technique. And in this example we're going to use a regular expression to do ROT13 ( a relatively trivial example, but it should illustrate the point)

Firstly you need a new project. Add a class to the project, and drop in the following code:
Code:
[blue]Option Explicit
[green]
' function template:
' replaceFunc(matchedString [, subMatch1 [, ...]] , matchPos, source)
' this is your custom replacer function. You can put your own code in here ...
' the template above should help you to figure out which parameter means what[/green]
Public Function ReplacerFunction(ParamArray a()) As String
    
End Function
[/blue]
Now select Tools/Procedure Attributes/Advanced and change the Procedure ID of the ReplacerFunction to (Default)

And that's it. You've now done the hard bit ...

As I said, for this example we're going to do ROT13 our custom replacement function needs to add 13 to the ASCII value of eached matched character, so we can drop this (very poor) code into our empty ReplacerFunction
Code:
[blue]Public Function ReplacerFunction(ParamArray a()) As String
    Dim j As Long
    j = Asc(a(0))
    If j >= 65 And j <= 90 Then
        j = ((j - 52) Mod 26) + 65
    ElseIf j >= 97 And j <= 122 Then
        j = ((j - 84) Mod 26) + 97
    End If
    ReplacerFunction = Chr(j)
End Function[/blue]
Ok, so now we need a form with two text boxes on it. And we drop in the following code:
Code:
[blue]Option Explicit
Private Sub Text1_Change()
    Dim myReplacer As Class1
    Dim re As RegExp
    
    Set myReplacer = New Class1
    Set re = New RegExp
    re.Global = True
    re.Pattern = "\w"
    Text2.Text = re.Replace(Text1.Text, myReplacer)
End Sub[/blue]

And there we go. ROT13 via a single RegExp replacement call.
 
>didnt understand it

Probabl;y because I haven't really included any explanation ...
 
Well, let's work backwards. First, the Replace method of the RegExp class:
Code:
Text2.Text = re.Replace(Text1.Text, myReplacer)
Since the replace method takes 2 strings, it follows that "myReplacer" evaluates to a string. Look at the class. It has a function called ReplacerFunction, which takes one argument, a variant array called a, and outputs a string. So. Also, ReplacerFunction is the default method, meaning it gets called when there is a reference to its object with no method or property. (Neat trick, I've only used this when making default properties.) So, in the code above, myReplacer can take any number of strings as arguments, then massage them via its replacerfunction method, and output a string that's valid in terms of the second argument of the Replace method.

That's mighty cool, but looking at the code, I'm thinking that there must be arguments passed to the above line for it to do any actual work. Furthermore, looking at the "very poor" code, I'm thinking it's very poor because it only evaluates the first member of the a array. So, I'm wondering if actual usage would be more like
Code:
Text2.Text = re.Replace(Text1.Text, myReplacer(strA, strB, ...))
And then having the method evaluate each string and cobble them together to send to the Replace method.

Some nice wrinkles in this code.

Bob
 
That's mighty cool, but looking at the code, I'm thinking that there must be arguments passed to the above line for it to do any actual work.

not really try this as your class code:

Option Explicit
Private intCount As Integer
Public Function ReplacerFunction(ParamArray a()) As String
intCount = intCount + 1
Select Case intCount
Case 1
ReplacerFunction = "NewValue"
Case 2
ReplacerFunction = "Another New Value"
Case Else
ReplacerFunction = "A newer Value"
End Select
End Function


strongm said:
If you're interested ...

Funny [lol] have a star.



Two strings walk into a bar. The first string says to the bartender: 'Bartender, I'll have a beer. u.5n$x5t?*&4ru!2[sACC~ErJ'. The second string says: 'Pardon my friend, he isn't NULL terminated'.
 
Ok, so I did a little testing here. The actual usage indeed does require an argument list. Neat piece of code, strongm. Thanks for sharing.

Bob
 
Ok, looking at your code, javajoe, that's true, but I meant to have the paramarray do any actual work, it needs to have something passed to it. Of course, you could use ismissing to see if anything was passed to it, and send back some default string if not, perhaps.

Bob
 
The ReplacerFunction would not be called unless something was passed to it. Each time a match is found the function gets called and a(0) is the replace value a(1) the location where it was found and finally a(2) the original string.

Here's something to look at:


Two strings walk into a bar. The first string says to the bartender: 'Bartender, I'll have a beer. u.5n$x5t?*&4ru!2[sACC~ErJ'. The second string says: 'Pardon my friend, he isn't NULL terminated'.
 
that is indeed very nice *slots into the toolbox*

If somethings hard to do, its not worth doing - Homer Simpson
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top