Replace whole word in string using Regex

Hi,

I want to replace whole words only (ignore cases) using regex.  I am using below method:

                   Set RegexObj = New RegExp

                    With RegexObj
                        .Pattern = "test"
                        .IgnoreCase = True
                        .Global = True
                    End With

                    objSafeMail.Body = RegexObj.Replace(objSafeMail.Body, "test2")

If string is "Mytest in regex test is the Testing for replace test" then above method gives below result.

       "Mytest2 in regex test2 is the Test2ing for replace test2"

but I want

      "Mytest in regex test2 is the Testing for replace test2"

Thanks.
LVL 1
deshawAsked:
Who is Participating?
 
Wayne Taylor (webtubbs)Commented:
>>Could you please explain me what below line does?

"([a-zA-Z]+)(\#[0-9]+){1,2}(?!\#)\b"

        ([a-zA-Z]+) =  any character of the a-zA-Z class, one or more times

        (\#[0-9]+){1,2} = match a #[0-9] combination, occurring between 1 and 2 times

        (?!\#) = Next character *is not* a hash. Used so it ignores those items with more than 2 number sets.

        \b = Last character in a word.

tmpstr = oRE.Replace(str, link & "$1/$&")

        $1 = the first group ([a-zA-Z]+)

        $& = The entire match

tmpstr = Replace(tmpstr, "/" & oMatch.submatches(0) & "#", "/")

         Because it'll create a string like "http://mylink/Q/Admin/Admin#123#2", it will replace "/Admin#" with a single slash.
         oMatch.submatches(0) returns the first group of the match, as found by ([a-zA-Z]+).

As for reference material, I use Expresso (http://www.ultrapico.com/Expresso.htm), which makes experimenting with Regex easy.

Wayne
0
 
wellsoCommented:
maybe ^(test)$ as your pattern?
0
 
deshawAuthor Commented:
Nop the output will be same and it will not replace any of "test". It replace it only if complete string itself "test" and not  "Mytest in regex test is the Testing for replace test".
Thanks.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Wayne Taylor (webtubbs)Commented:
Use this pattern....

    .Pattern = "\btest\b"

Wayne
0
 
deshawAuthor Commented:
"\btest\b" - word boundery replaces all the "test" words. The output is    "Mytest2 in regex test2 is the Test2ing for replace test2". Also in  "this is test." it will not replace test as '.' is there.
Could you tell me is it possible to make regex something like this:
<Don't care what is here: space, dot,  nothing, or whatever but not alphanumeric> test <nothing should be here other than dot, space, newline or nothing>
Thanks,
0
 
Wayne Taylor (webtubbs)Commented:
>>The output is "Mytest2 in regex test2 is the Test2ing for replace test2"

No, it's not. The output is "Mytest in regex test2 is the Testing for replace test2". I know this because I tested it before posting.

>>Also in  "this is test." it will not replace test as '.' is there.

Yes, it will. The below example works exactly as you requested. Please try it. You will see the output is like this....

    "Testing - testing, XXXX, this is a XXXX."

Wayne
     Dim s As String
     s = "Testing - testing, test, this is a test."
 
    Dim RegexObj As New RegExp
 
     With RegexObj
          .Pattern = "\btest\b"
          .IgnoreCase = True
          .Global = True
     End With
 
     MsgBox RegexObj.Replace(s, "XXXX")

Open in new window

0
 
deshawAuthor Commented:
Ok let me give you the real case: Please just run the attached code and you will come to know what I am asking. When you run the code, first message box will be displayed as
"Sys#123#1" string and next message box I am displaying original string and you could see that it will replace  "Sys#123#1#3"with the link string along with "Sys#123#1" though I have used word boundry given by you. Actually it is replacing  "Sys#123#1" in "Sys#123#1#3" string but it should not happen because we used "\b".
 Please let me know what is wrong.
Thanks,.

ub RegextTest()
 
    Const link = "http://mylink/Q/{match}/{NNN}"
    Const MY_PATTERN = "[a-zA-Z]{1,}#{1,1}[0-9]{1,}#{0,1}[0-9]{1,}"
    Dim oRE As Object
    Dim oMatches As Object
    Dim str As String
    Dim tmpstr As String
 
    Set oRE = CreateObject("VBScript.Regexp")
 
    With oRE
        .IgnoreCase = True
        .Global = True
        .MultiLine = True
        .Pattern = MY_PATTERN
    End With
    
    str = "Sys#123#1" & vbCrLf & "Admin#123#1#3" & vbCrLf & "Admin#123#1#3" & vbCrLf & "Sys#123#1#3"
    Set oMatches = oRE.Execute(str)
    
    For Each omatch In oMatches
         MsgBox omatch
         Dim s1() As String
         s1 = Split(omatch, "#")
         tmpstr = link
         tmpstr = Replace(tmpstr, "{match}", s1(0))
                   
         If UBound(s1) > 1 Then
              tmpstr = Replace(tmpstr, "{NNN}", s1(1) & "#" & s1(2))
         Else
              tmpstr = Replace(tmpstr, "{NNN}", s1(1))
         End If
                                        
         Set RegexObj = New RegExp
 
         With RegexObj
             .Pattern = "\b" & omatch & "\b"
             .IgnoreCase = True
             .Global = True
         End With
         
         str = RegexObj.Replace(str, tmpstr)
         MsgBox str
     Next
End Sub

Open in new window

0
 
deshawAuthor Commented:
with    Const MY_PATTERN = "\b[a-zA-Z]{1,}#{1,1}[0-9]{1,}#{0,1}[0-9]{1,}\b" also gives same behavior.
Thanks.
0
 
deshawAuthor Commented:
more simple. Why it is matching 4 times in given program? It should only 2 times. Isn't it?
Thanks.

Sub RegextTest()
 
    Const MY_PATTERN = "\b[a-zA-Z]{1,}#{1,1}[0-9]{1,}#{0,1}[0-9]{1,}\b"
    Dim oRE As Object
    Dim oMatches As Object
    Dim str As String
 
    Set oRE = CreateObject("VBScript.Regexp")
 
    With oRE
        .IgnoreCase = True
        .Global = True
        .Pattern = MY_PATTERN
    End With
    
    str = "Sys#123#1" & vbCrLf & "Admin#123#1#3" & vbCrLf & "Admin#123#2" & vbCrLf & "Sys#123#1#3"
    
    Set oMatches = oRE.Execute(str)
    
    MsgBox oMatches.Count
    
    For Each omatch In oMatches
         MsgBox omatch
     Next
End Sub

Open in new window

0
 
deshawAuthor Commented:
In your example, if you put # after test, it will give below output
XXXX#ing - XXXX#ing, XXXX, this is a XXXX.
which is wrong.

 Dim s As String
     s = "Test#ing - test#ing, test, this is a test."
 
    Dim RegexObj As New RegExp
 
     With RegexObj
          .Pattern = "\btest\b"
          .IgnoreCase = True
          .Global = True
     End With
 
     MsgBox RegexObj.Replace(s, "XXXX")
 

Open in new window

0
 
Wayne Taylor (webtubbs)Commented:
I'll take a look at your example, but first, regarding "Test#ing", that's 2 words, "Test" and "ing", so is correctly replacing the words.
0
 
Wayne Taylor (webtubbs)Commented:
Using your last example, you could use this pattern

    [a-zA-Z]{1,}\#[0-9]{1,}\#[0-9]{1,}\r\n

If you could outline exactly what you are trying to achieve, we will probably be able to assist more.

Wayne
0
 
deshawAuthor Commented:
If "Test#ing" two words then usage of word boundry "\b" won't work for me.
" [a-zA-Z]{1,}\#[0-9]{1,}\#[0-9]{1,}\r\n" either won't work in all situation. if valid string followed by space and not \r or \n then it won't return that as a match.
I tell you precisely what I want. I want to replace [a-zA-Z]#[0-9] or [a-zA-Z]#[0-9]#[0-9] strings and nothing else (e;g [a-zA-Z]#[0-9]#[0-9] #[0-9] should not be replaced) with the link  in whole string.
Let me know if I am not clear.
Thanks.
0
 
deshawAuthor Commented:
I mean [a-zA-Z]#[0-9]#[0-9] pattern should not be detected and replaced in [a-zA-Z]#[0-9]#[0-9] #[0-9]  string.
Thanks.
0
 
Wayne Taylor (webtubbs)Commented:
If I understand correctly, try this pattern....

    [a-zA-Z]+(?:\#[0-9]+){1,2}(?!\#)\b

For this string....

Sys#123#1
Admin#123#1#3
Admin#123#2
Admin#123
Sys#123#1#3

...it will only match these...

Sys#123#1
Admin#123#2
Admin#123

Wayne
0
 
deshawAuthor Commented:
Perfect, it identifies the correct matches only. Could you also tell me how we will replace it with the link. In attached script MY_PATTERN is what you have suggested. I want to replaced only matched items. It should not replaced unmatched item. for example currently Sys#123#1#3 is getting replaced by link.
If I keep same my pattern while replacing like below:
  Set RegexObj = New RegExp
 
         With RegexObj
             .Pattern = omatch & "(?:\#[0-9]+){1,2}(?!\#)\b"
             .IgnoreCase = True
             .Global = True
         End With
         
         str = RegexObj.Replace(str, tmpstr)
then it replacing all unmatched items. :-) I think something is missing. You can only help here. :-)
Complete code I have attached.
Thanks.

Sub RegextTest()
 
    Const MY_PATTERN = "[a-zA-Z]+(?:\#[0-9]+){1,2}(?!\#)\b"
    Const link = "http://mylink/Q/{match}/{NNN}"
 
    Dim oRE As Object
    Dim oMatches As Object
    Dim str As String
    Dim tmpstr As String
 
    Set oRE = CreateObject("VBScript.Regexp")
 
    With oRE
        .IgnoreCase = True
        .Global = True
        .MultiLine = True
        .Pattern = MY_PATTERN
    End With
    
    str = "Sys#123#1" & vbCrLf & "Admin#123#1#3" & vbCrLf & "Admin#123#1 Sys#123#1#3"
    Set oMatches = oRE.Execute(str)
    
    For Each omatch In oMatches
         MsgBox omatch
         Dim s1() As String
         s1 = Split(omatch, "#")
         tmpstr = link
         tmpstr = Replace(tmpstr, "{match}", s1(0))
                   
         If UBound(s1) > 1 Then
              tmpstr = Replace(tmpstr, "{NNN}", s1(1) & "#" & s1(2))
         Else
              tmpstr = Replace(tmpstr, "{NNN}", s1(1))
         End If
                                        
         Set RegexObj = New RegExp
 
         With RegexObj
             .Pattern = omatch & "(?:\#[0-9]+){1,2}(?!\#)\b"
             .IgnoreCase = True
             .Global = True
         End With
         
         str = RegexObj.Replace(str, tmpstr)
         MsgBox str
     Next
End Sub

Open in new window

0
 
Wayne Taylor (webtubbs)Commented:
Can you show exactly how these should look after the replacing is done?

Sys#123#1
Admin#123#1#3
Admin#123#2
Admin#123
Sys#123#1#3
0
 
deshawAuthor Commented:
Out of below items:
Sys#123#1
Admin#123#1#3
Admin#123#2
Admin#123
Sys#123#1#3
following valid items should be get converted:
Sys#123#1
Admin#123#2
Admin#123

to
http://mylink/Q/Sys/123#1
http://mylink/Q/Admin/123#2
http://mylink/Q/Admin/123
 In my program below lines separating items by #.  The form "tmpstr" will be the final link that will replace original matched items.
         s1 = Split(omatch, "#")
         tmpstr = link
         tmpstr = Replace(tmpstr, "{match}", s1(0))
                   
         If UBound(s1) > 1 Then
              tmpstr = Replace(tmpstr, "{NNN}", s1(1) & "#" & s1(2))
         Else
              tmpstr = Replace(tmpstr, "{NNN}", s1(1))
         End If
 
Thanks.
0
 
Wayne Taylor (webtubbs)Commented:
OK, I think I have it. Try the below code and see how it goes.

Wayne
Sub RegextTest()
 
     Const MY_PATTERN = "([a-zA-Z]+)(\#[0-9]+){1,2}(?!\#)\b"
     Const link = "http://mylink/Q/"
 
     Dim oRE As Object
     Dim oMatches As Object, oMatch As Object
     Dim str As String
     Dim tmpstr As String
 
     Set oRE = CreateObject("VBScript.Regexp")
 
     With oRE
          .IgnoreCase = True
          .Global = True
          .MultiLine = True
          .Pattern = MY_PATTERN
     End With
 
     str = "Sys#123#1" & vbCrLf & "Admin#123#1#3" & vbCrLf & "Admin#123#1" & vbCrLf & "Sys#123#1#3"
 
     tmpstr = oRE.Replace(str, link & "$1/$&")
     Set oMatches = oRE.Execute(str)
     
     For Each oMatch In oMatches
          tmpstr = Replace(tmpstr, "/" & oMatch.submatches(0) & "#", "/")
     Next
 
     MsgBox str & vbCrLf & vbCrLf & tmpstr
 
End Sub

Open in new window

0
 
deshawAuthor Commented:
fantabulous webtubbs, what a great logic !!! Could you please explain me what below line does?
  "([a-zA-Z]+)(\#[0-9]+){1,2}(?!\#)\b"

   tmpstr = oRE.Replace(str, link & "$1/$&")
   tmpstr = Replace(tmpstr, "/" & oMatch.submatches(0) & "#", "/")

 Could you please suggest any material to read about Regular Expression so that I can also think like you. :-)
Thanks.
0
 
deshawAuthor Commented:
Then I think  "tmpstr = oRE.Replace(str, link & "$&")" will be enough. see attached code:
let me know if it is correct.
Thanks.

Sub RegextTest()
 
     Const MY_PATTERN = "([a-zA-Z]+)(\#[0-9]+){1,2}(?!\#)\b"
     Const link = "http://mylink/Q/"
 
     Dim oRE As Object
     Dim oMatches As Object, oMatch As Object
     Dim str As String
     Dim tmpstr As String
 
     Set oRE = CreateObject("VBScript.Regexp")
 
     With oRE
          .IgnoreCase = True
          .Global = True
          .MultiLine = True
          .Pattern = MY_PATTERN
     End With
 
     str = "Sys#123#1" & vbCrLf & "Admin#123#1#3" & vbCrLf & "Admin#123#1" & vbCrLf & "Sys#123#1#3"
 
     tmpstr = oRE.Replace(str, link & "$&")     
     MsgBox str & vbCrLf & vbCrLf & tmpstr
 
End Sub

Open in new window

0
 
Wayne Taylor (webtubbs)Commented:
If you do that, then this....

    Sys#123#1

...will end up like this....

    http://mylink/Q/Sys#123#1

I thought you wanted it to be "http://mylink/Q/Sys/123#1"?

Wayne
0
 
deshawAuthor Commented:
Yup...you are correct. :-)
thanks.
0
 
deshawAuthor Commented:
thanks.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.