VBAtoPython

VBA RegExp to Python re Module

VBA regex requires creating a VBScript.RegExp COM object with limited pattern support. Python's built-in re module is far more powerful, with lookaheads, named groups, and no COM overhead.

VBA RegExp Example

VBA

Sub ExtractEmailsFromText()
    ' Extract email addresses from a text string and capture parts
    Dim rx As Object
    Dim inputText As String
    Dim matches As Object
    Dim match As Object
    Dim i As Integer
    
    ' Create RegExp object
    Set rx = CreateObject("VBScript.RegExp")
    
    ' Configure pattern for email extraction with capture groups
    rx.Pattern = "([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"
    rx.Global = True
    rx.IgnoreCase = True
    
    inputText = "Contact us at support@company.com or sales@example.org for assistance."
    
    ' Test if pattern exists
    If rx.Test(inputText) Then
        Debug.Print "Emails found!"
        
        ' Execute and iterate through matches
        Set matches = rx.Execute(inputText)
        For Each match In matches
            Debug.Print "Full email: " & match.Value
            Debug.Print "Username: " & match.SubMatches(0)
            Debug.Print "Domain: " & match.SubMatches(1)
            Debug.Print "Position: " & match.FirstIndex & ", Length: " & match.Length
        Next match
    End If
End Sub

Python re module Equivalent

Python

import re
from typing import List, Tuple

def extract_emails_from_text() -> None:
    """Extract email addresses from a text string and capture parts."""
    # Compile pattern with capture groups (case-insensitive)
    pattern = re.compile(
        r"([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})",
        re.IGNORECASE
    )
    
    input_text = "Contact us at support@company.com or sales@example.org for assistance."
    
    # Test if pattern exists
    if re.search(pattern, input_text):
        print("Emails found!")
        
        # Find all matches with position information
        for match in re.finditer(pattern, input_text):
            print(f"Full email: {match.group(0)}")
            print(f"Username: {match.group(1)}")
            print(f"Domain: {match.group(2)}")
            print(f"Position: {match.start()}, Length: {len(match.group(0))}")

if __name__ == "__main__":
    extract_emails_from_text()

Common VBA → Python Mappings

VBA RegExpPython re module
Set rx = CreateObject("VBScript.RegExp")import re; rx = re.compile(pattern)
rx.Pattern = "pattern"re.compile(r"pattern")
rx.Global = Truere.findall() or re.finditer()
rx.Test(text)bool(re.search(pattern, text))
rx.Execute(text)re.finditer(pattern, text)
match.SubMatches(0)match.group(1)

Side-by-Side Comparison

VBA

Function ValidatePhoneNumber(phoneNum As String) As Boolean
    Dim rx As Object
    Set rx = CreateObject("VBScript.RegExp")
    rx.Pattern = "^\(\d{3}\) \d{3}-\d{4}$"
    rx.IgnoreCase = False
    ValidatePhoneNumber = rx.Test(phoneNum)
End Function

Python

import re

def validate_phone_number(phone_num: str) -> bool:
    """Validate phone number format: (123) 456-7890"""
    pattern = r"^\(\d{3}\) \d{3}-\d{4}$"
    return bool(re.match(pattern, phone_num))

Important Differences

  • Group Indexing: VBA SubMatches use 0-based indexing while Python groups use 1-based indexing. Python's group(0) returns the full match.
  • Raw Strings: Python regex patterns should use raw strings (r"pattern") to avoid escaping backslashes, unlike VBA strings.
  • Global Matching: VBA requires rx.Global = True for multiple matches. Python's findall() and finditer() are global by default.
  • Feature Support: Python re module supports advanced features like lookbehind, named groups, and non-greedy quantifiers that VBA RegExp lacks.

Have VBA macros using RegExp patterns?

Convert your regex code to Python's more powerful re module instantly.