Microsoft Office Forums

Go Back   Microsoft Office Forums > >

Reply
 
Thread Tools Display Modes
  #1  
Old 01-07-2025, 09:03 AM
gmaxey gmaxey is online now Find Challenge Windows 10 Find Challenge Office 2019
Expert
Find Challenge
 
Join Date: May 2010
Location: Brasstown, NC
Posts: 1,601
gmaxey is just really nicegmaxey is just really nicegmaxey is just really nicegmaxey is just really nicegmaxey is just really nice
Default

Batman1,


Very interesting. After studying your last (which works perfectly), I thought I would modify slightly just to confirm my understanding. The result is a little simpler for me to understand and will provide notes for myself should I ever need to revisit.



Thanks again for your lessons in RegEx:




Code:
Sub RegExPsuedoLookBack()
Dim RegEx As Object, Matches As Object, Match As Object
Dim oRng As Range
'Sample document text: Jack Sprat, Johnny Sprat, Tom Sprat, Mary Sprat and Bill Sprat.
  'With RegEx look ahead, you can find all instances of x = "Sprat" preceded by either y = "Jack " or y = "Tom "
  Set RegEx = CreateObject("VBScript.RegExp")
  With RegEx
    .Global = True
    .Pattern = "(?=Tom|Jack)\S+ Sprat"
  End With
  Set Matches = RegEx.Execute(ActiveDocument.Range.Text)
  For Each Match In Matches
    'Returns all instances of "Sprat" immediately after "Tom " or "Jack ".
    Debug.Print Match.Value 'Notice the match return includes the proceeding y qualifyer.
  Next
  'A RegEx look back will return all instances of x = "Sprat" preceded by y = "Jack " or y = "Tom " but the match return only inclues the x value "Sprat"
  Set RegEx = CreateObject("VBScript.RegExp")
  With RegEx
    .Global = True
    .Pattern = "(?<=Tom |Jack )\Sprat"
  End With
  On Error GoTo lbl_EH
  Set Matches = RegEx.Execute(ActiveDocument.Range.Text)
  For Each Match In Matches
    'If this worked, it would return all instances of "Sprat" immediately after "Tom " or "Jack ".
    Debug.Print Match.Value
  Next
lbl_ER:
  'VBA workaround for RegEx look back.
  With RegEx
    .Global = True
    'Use a modified look ahead as demonstrated previously.
    .Pattern = "((?=Tom|Jack)\S+ )Sprat" 'Note the addition of parens "()" around the y element will result in a submatch.
  End With
  Set Matches = RegEx.Execute(ActiveDocument.Range.Text)
  For Each Match In Matches
    'Returns x = "Jack Sprat" and "Tom Sprat" matches at before.
    'However, also returns the submatches "Jack " from the "Jack Sprat" match and "Tom " from the "Tom Sprat" match.
    'Use these manipulate the returned range to achieve a VBA pseudo lookback method.
    ActiveDocument.Range(Match.FirstIndex + Len(Match.Submatches(0)), Match.FirstIndex + Match.Length).HighlightColorIndex = wdBrightGreen
  Next
lbl_Exit:
  Exit Sub
lbl_EH:
  MsgBox "Unfortunatley RegEx look back is not supported in VBA." & vbCr + vbCr _
       & "Proceding to work around.", vbInformation + vbOKOnly, "INVALID OPERATION"
  Resume lbl_ER
End Sub

Please feel free to further comment, if my notes above could be clarified further.
__________________
Greg Maxey
Please visit my web site at http://www.gregmaxey.com/
Reply With Quote
  #2  
Old 01-07-2025, 01:37 PM
batman1 batman1 is offline Find Challenge Windows 11 Find Challenge Office 2013
Advanced Beginner
 
Join Date: Jan 2025
Posts: 57
batman1 is on a distinguished road
Default

Quote:
Originally Posted by gmaxey View Post
'Note the addition of parens "()" around the y element will result in a submatch.
This is Backreferences.

With Backreferences:
1. You can use submatch
2. You can refer to an earlier group later in the Pattern ()
3. You can use submatch in REPLACE

Note 1.
You already use it in your code.

Note 2.
Pattern = "([A-Za-z]+) \1"

Pattern = <series1><space><series2>, where <series1> and <series2> are identical

E.g. Pattern = "([A-Za-z]+) \1" will find "a a", "John John". If .IgnoreCase = True then it will also find "A a"

a Pattern = "([A-Za-z]+) ([A-Za-z]+) \2 \1" will find "Jack Sprat Sprat Jack

Note 3.

In Repace we don't use \1, \2, … We use $1, $2, …
Code:
Sub test2()
Dim RegEx As Object, Matches As Object, Match As Object, text As String
    text = "Fellow John John is a good student. Fellow Jack Jack also"
    
    Debug.Print text
    
    Set RegEx = CreateObject("VBScript.RegExp")
    With RegEx
        .Global = True
        .Pattern = "([A-Za-z]+) \1"
        If .test(text) Then
            text = .Replace(text, "$1") ' in every place in string Text where a result is found, that result is replaced with its $1
            
            Debug.Print text
            
        End If
    End With
    
    text = "John Smith is a good student. Jack Sprat also"
    With RegEx
        .Global = True
        .Pattern = "([A-Z][a-z]+) ([A-Z][a-z]+)"
        If .test(text) Then
            text = .Replace(text, "$2 $1")
            
            Debug.Print text
            
        End If
    End With
End Sub
Reply With Quote
Reply



Similar Threads
Thread Thread Starter Forum Replies Last Post
Any work-around for this challenge RRB Word 6 08-22-2023 11:47 AM
Formula challenge 3 criteria JMC44 Excel Programming 0 04-04-2015 07:38 PM
Find Challenge Challenge for a genius ? e.roberts Office 3 07-13-2012 01:36 AM
Find Challenge Sorting Challenge gbaker Excel Programming 11 06-22-2012 09:39 AM
Find Challenge Word Challenge jpotter2 Word 3 03-22-2011 02:07 PM

Other Forums: Access Forums

All times are GMT -7. The time now is 01:53 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.
Search Engine Optimisation provided by DragonByte SEO (Lite) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
MSOfficeForums.com is not affiliated with Microsoft