
El fin de RegEx en VBA ¡no tan rápido!
Hace poco, Mike Wolfe mencionó que Microsoft había anunciado que iban a eliminar gradualmente y retirar VBScript.


Y las implicaciones de esto podrían ser de largo alcance y afectar todo tipo de cosas, en particular la posible pérdida de:
- Objeto del sistema de archivos (FSO)
- Expresiones regulares (RegEx)
- y más
Lo único que se ha dicho oficialmente es
Ahora seamos claros aquí, todos somos… aún Estamos esperando a que Microsoft aclare el tema para saber al 100% qué se perderá cuando esto ocurra y qué bibliotecas desaparecerán. Hasta ahora todo son suposiciones lógicas basadas en lo que sabemos de las bibliotecas, pero hasta la fecha no se han dado detalles oficiales.Y sí, mucha gente ha pedido aclaraciones, pero hasta ahora no se ha dado ninguna.)
Después de años de esperar a que Microsoft brindara información pública sobre diversos temas y nunca se materializó o tardó demasiado, decidí no esperar en este asunto. Quería intentar prepararme lo mejor posible por si ocurrían cosas así. ¡Planifique ahora en lugar de entrar en pánico más tarde!
Por eso he decidido compartir mi trabajo aquí con la esperanza de que pueda ayudar a otros.
Inicialmente, decidí concentrarme en ver si no había otro enfoque que pudiera usarse en VBA para proporcionar la funcionalidad RegEx sin el uso de la biblioteca RegulareExpression de VBScript (CrearObjeto(“VBScript.RegExp”)) Para ello recurrí a mi experiencia en desarrollo web.
Las expresiones regulares son comunes en el desarrollo web y sabía que probablemente podría hacer algo a través de los controles del navegador web, pero no quería tener que requerir algún formulario oculto… Eso simplemente no sería lo ideal. Luego recordé haber hecho algo de JS a través del código cuando quise extraer la URL base de una URL completa que empleaba el uso del control de secuencia de comandos.
Ahora bien, no vi el control de script (msscript.ocx) mencionado en el artículo de Mike, por lo que espero que no sea parte de la desuso de VB Script.
Con este conocimiento en la mano, pude obtener funcionalidades de RegEx sin la necesidad de las bibliotecas mencionadas en el artículo de Mike, ni usar ningún objeto de base de datos para que todo esto sucediera. Este enfoque debería funcionar en cualquier entorno VBA (Access, Excel, Outlook, PowerPoint, Word, etc.).
Validación
Si queremos realizar validaciones RegEx, ahora podemos hacer algo como:
'---------------------------------------------------------------------------------------
' Procedure : JSRegEx_Validate
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website :
' Purpose : Performs RegEx validation via the Script Control ocx instead of the
' VBScript RegulareExpression.
' It returns True if it is valid, otherwise it returns False
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) -
' Req'd Refs: Late Binding -> None required
' Early Binding -> Micrsoft Script Control X.X
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPattern : The RegEx pattern to test the object against
' sPatternFlags : The RegEx pattern flags to use
' vInput : The Object to validate against the specified pattern
'
' Usage:
' ~~~~~~
' Validate URL
' ? JSRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.google.ca")
' Returns => True
'
' ? JSRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.googleca")
' Returns => False
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2024-03-02 Initial Release
'---------------------------------------------------------------------------------------
Public Function JSRegEx_Validate(ByVal sPattern As String, _
ByVal sPatternFlags As String, _
ByVal vInput As Variant) As String
On Error GoTo Error_Handler
#Const ScriptControl_EarlyBind = False 'Should normally be in the Module header
#If ScriptControl_EarlyBind = True Then
Dim oSC As MSScriptControl.ScriptControl
Set oSC = New ScriptControl
#Else
Static oSC As Object
Set oSC = CreateObject("ScriptControl")
#End If
Dim sOutput
If Not oSC Is Nothing Then
With oSC
.Language = "JScript"
' '? JSRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.google.ca")
' .AddCode "function regEx_Pattern_Test(myInput) {" & _
' " var regEx_Pattern = " & sPattern & sPatternFlags & ";" & _
' " return regEx_Pattern.test(myInput);" & _
' "}"
' sOutput = .Run("regEx_Pattern_Test", vInput)
'? JSRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.google.ca")
.AddCode "function regEx_Pattern_Test(myPattern, myPatternFlags, myInput) {" & _
" var regEx_Pattern = eval(myPattern + myPatternFlags);" & _
" return regEx_Pattern.test(myInput);" & _
"}"
sOutput = .Run("regEx_Pattern_Test", sPattern, sPatternFlags, vInput)
End With
End If
JSRegEx_Validate = sOutput
Error_Handler_Exit:
On Error Resume Next
Set oSC = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Source: JSRegEx_Validate" & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
o
'---------------------------------------------------------------------------------------
' Procedure : JSRegEx_Validate
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website :
' Purpose : Performs RegEx validation via the Script Control ocx instead of the
' VBScript RegulareExpression.
' It returns True if it is valid, otherwise it returns False
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) -
' Req'd Refs: Late Binding -> None required
' Early Binding -> Micrsoft Script Control X.X
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPattern : The RegEx pattern to test the object against
' sPatternFlags : The RegEx pattern flags to use
' vInput : The Object to validate against the specified pattern
'
' Usage:
' ~~~~~~
' Validate URL
' ? JSRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.google.ca")
' Returns => True
'
' ? JSRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.googleca")
' Returns => False
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2024-03-02 Initial Release
'---------------------------------------------------------------------------------------
Public Function JSRegEx_Validate(ByVal sPattern As String, _
ByVal sPatternFlags As String, _
ByVal vInput As Variant) As String
On Error GoTo Error_Handler
'#Const ScriptControl_EarlyBind = False 'Should normally be in the Module header
#If ScriptControl_EarlyBind = True Then
Dim oSC As MSScriptControl.ScriptControl
Set oSC = New ScriptControl
#Else
Static oSC As Object
Set oSC = CreateObject("ScriptControl")
#End If
Dim sOutput
If Not oSC Is Nothing Then
With oSC
.Language = "JScript"
'? JSRegEx_Validate("^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$", "igm", "www.google.ca")
.AddCode "function regEx_Pattern_Test(myPattern, myPatternFlags, myInput) {" & _
" var regEx_Pattern = new RegExp(myPattern, myPatternFlags);" & _
" return regEx_Pattern.test(myInput);" & _
"}"
sOutput = .Run("regEx_Pattern_Test", sPattern, sPatternFlags, vInput)
End With
End If
JSRegEx_Validate = sOutput
Error_Handler_Exit:
On Error Resume Next
Set oSC = Nothing
Exit Function
Error_Handler:
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Source: JSRegEx_Validate" & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Validar una URL
Podrías utilizar lo anterior haciendo:
? JSRegEx_Validate("^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$", "igm", "www.google.ca")
which will return True
? JSRegEx_Validate("^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$", "igm", "www.googleca")
which will return False
También podríamos crear una función auxiliar de contenedor para varias pruebas comunes: URL, correo electrónico, teléfono, etc., para simplificar la codificación y el uso. Por ejemplo, para validar URL, podríamos hacer lo siguiente:
Public Function JSRegEx_Validate_URL(ByVal sURL As Variant) As Boolean
Const sPattern = "/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/"
Const sPatternFlags = "igm"
JSRegEx_Validate_URL = JSRegEx_Validate(sPattern, sPatternFlags, sURL)
End Function
y luego la validación se vuelve mucho más sencilla y solo requiere:
? JSRegEx_Validate_URL("www.google.ca") 'Returns True
? JSRegEx_Validate_URL("www.googleca") 'Returns False
Extrayendo coincidencias
De manera similar a lo anterior, podemos desarrollar fácilmente una función RegEx Match universal que utilice el ocx de control de secuencia de comandos para buscar y extraer segmentos de una cadena más grande que coincidan con un patrón específico. Por lo tanto, no solo se prueba si se cumple, sino que se extrae el segmento coincidente.
Podemos hacer algo como:
'---------------------------------------------------------------------------------------
' Procedure : JSRegEx_Matches
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website :
' Purpose : Uses Script Control ocx RegEx to extract the matches of the defined
' pattern.
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) -
' Req'd Refs: Late Binding -> None required
' Early Binding -> Micrsoft Script Control X.X
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPattern : The RegEx pattern to test the object against and extract macthes of
' sPatternFlags : The RegEx pattern flags to use
' vInput : The Object to validate against the specified pattern
' sDelimiter : Delimiter to be used to separate the matches in the returned string
' If omitted , is used
'
' Usage:
' ~~~~~~
' Extract E-mail addresses from a string
' ? JSRegEx_Matches("((a-zA-ZF0-9\u00C0-\u017F._-)+@(a-zA-Z0-9\u00C0-\u017F._-)+\.(a-zA-Z0-9\u00C0-\u017F_-)+)", _
' "gmi", _
' "some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .")
' Returns => dani@ccc.com, marth@marth.ru, carl@hotmail.com
'
' ? JSRegEx_Matches("((a-zA-ZF0-9\u00C0-\u017F._-)+@(a-zA-Z0-9\u00C0-\u017F._-)+\.(a-zA-Z0-9\u00C0-\u017F_-)+)", _
' "gmi", _
' "some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .", _
' "~")
' Returns => dani@ccc.com~marth@marth.ru~carl@hotmail.com
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2024-03-02 Initial Release
'---------------------------------------------------------------------------------------
Public Function JSRegEx_Matches(ByVal sPattern As String, _
ByVal sPatternFlags As String, _
ByVal vInput As Variant, _
Optional sDelimiter As String = ", ") As String
On Error GoTo Error_Handler
'#Const ScriptControl_EarlyBind = False 'Should normally be in the Module header
#If ScriptControl_EarlyBind = True Then
Dim oSC As MSScriptControl.ScriptControl
Set oSC = New ScriptControl
#Else
Static oSC As Object
Set oSC = CreateObject("ScriptControl")
#End If
Dim sScript As String
Dim sOutput As String
If Not oSC Is Nothing Then
With oSC
.Language = "JScript"
sScript = "function patternTest(myPattern, myPatternFlags, myInput, myDelimiter) {" & _
" var reg = new RegExp(myPattern, myPatternFlags);" & _
" var output="";" & _
" var matches = myInput.match(reg);" & _
" if(matches && matches.length != 0){" & _
" for (var i = 0; i 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
Resume Error_Handler_Exit
End Function
Extracción de direcciones de correo electrónico
A continuación se muestra un ejemplo sencillo de cómo se podría utilizar esto para extraer todas las direcciones de correo electrónico de una cadena.
? JSRegEx_Matches("((a-zA-ZF0-9\u00C0-\u017F._-)+@(a-zA-Z0-9\u00C0-\u017F._-)+\.(a-zA-Z0-9\u00C0-\u017F_-)+)", _
"gmi", _
"some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .")
que luego volvería
dani@ccc.com, marth@marth.ru, carl@hotmail.com
Al igual que en la sección anterior, podríamos simplificar el uso frecuente creando funciones auxiliares de envoltura simples como:
Public Function JSRegEx_Extract_Emails(ByVal sInput As String) As String
Const sPattern = "((a-zA-ZF0-9\u00C0-\u017F._-)+@(a-zA-Z0-9\u00C0-\u017F._-)+\.(a-zA-Z0-9\u00C0-\u017F_-)+)"
Const sPatternFlags = "igm"
Const sDelim = "||"
JSRegEx_Extract_Emails = JSRegEx_Matches(sPattern, sPatternFlags, sInput, sDelim)
End Function
y que llamaríamos haciendo:
?JSRegEx_Extract_Emails("some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .")
which returns => dani@ccc.com||marth@marth.ru||carl@hotmail.com
O podríamos en cambio crear un contenedor como:
Public Function JSRegEx_Extract_Emails(ByVal sInput As String) As Variant
Const sPattern = "((a-zA-ZF0-9\u00C0-\u017F._-)+@(a-zA-Z0-9\u00C0-\u017F._-)+\.(a-zA-Z0-9\u00C0-\u017F_-)+)"
Const sPatternFlags = "igm"
Const sDelim = "||"
JSRegEx_Extract_Emails = Split(JSRegEx_Matches(sPattern, sPatternFlags, sInput, sDelim), sDelim)
End Function
que podríamos utilizar así:
Sub JSRegEx_Extract_Emails2_Test()
Dim aEmails As Variant
Dim i As Long
Const myString = "some text with dani@ccc.com and marth@marth.ru. carl@hotmail.com Some more text ."
aEmails = JSRegEx_Extract_Emails(myString)
For i = 0 To UBound(aEmails)
Debug.Print aEmails(i)
Next i
End Sub
que luego daría como resultado
dani@ccc.com marth@marth.ru carl@hotmail.com
Notas sobre el uso del control de script
Mientras desarrollaba mi código y lo probaba, descubrí un par de cosas que debes tener en cuenta si deseas realizar algún desarrollo utilizando el Control de Script, en particular:
- JScript no acepta // para comentarios en línea. Debemos utilizar la sintaxis /* */.
- JScript no admite ‘let’, ‘const’, etc. para declarar variables. ¡Por eso, use ‘var’ para prácticamente todo!
Básicamente, la versión de JS es antigua y no es compatible con ninguna de las sintaxis más nuevas. Por lo tanto, mantén las cosas lo más simples posible, incluso si eso infringe lo que hoy consideraríamos una práctica recomendada. De lo contrario, obtendrás todo tipo de errores muy extraños que realmente no indican la verdadera naturaleza del problema con tu código, errores como:
Error 1004 – Se esperaba ‘;’
Error 1009 – Se esperaba ‘}’
Si está interesado en la codificación de control de scripts con JScript, es posible que desee consultar:


Una técnica alternativa: utilizar la biblioteca de objetos HTML de Microsoft (MSHTML)
También quería demostrar rápidamente que incluso podríamos utilizar la biblioteca MSHTML. A continuación, se muestra un ejemplo de una función de validación que utiliza MSHTML.
'---------------------------------------------------------------------------------------
' Procedure : MSHTMLRegEx_Validate
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website :
' Purpose : Performs RegEx validation via the Microsoft HTML Object Library instead of
' the VBScript RegulareExpression.
' It returns True if it is valid, otherwise it returns False
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) -
' Req'd Refs: Late Binding -> None required
' Early Binding -> Microsoft HTML Object Library (mshtml.tlb)
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPattern : The RegEx pattern to test the object against
' sPatternFlags : The RegEx pattern flags to use
' vInput : The Object to validate against the specified pattern
'
' Usage:
' ~~~~~~
' Validate URL
' ? MSHTMLRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.google.ca")
' Returns => True
'
' ? MSHTMLRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "www.googleca")
' Returns => False
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2024-03-02 Initial Release
'---------------------------------------------------------------------------------------
Public Function MSHTMLRegEx_Validate(ByVal sPattern As String, _
ByVal sPatternFlags As String, _
ByVal vInput As Variant) As Boolean
#Const HF_EarlyBind = True 'True => Early Binding -> Microsoft HTML Object Library (mshtml.tlb)
'False => Late Binding
'Typically a Global Module Level Variable
#If HF_EarlyBind = True Then
Dim oHTMLFile As MSHTML.HTMLDocument
Dim oElem As MSHTML.HTMLGenericElement
Dim oLink As MSHTML.HTMLLinkElement
Dim oTable As MSHTML.HTMLTable
Dim oTr As MSHTML.HTMLTableRow
Dim oTd As MSHTML.HTMLTableCell
Set oHTMLFile = New MSHTML.HTMLDocument
#Else
Dim oHTMLFile As Object
Dim oElem As Object
Dim oLink As Object
Dim oTable As Object
Dim oTr As Object
Dim oTd As Object
Set oHTMLFile = CreateObject("HTMLFile")
#End If
oHTMLFile.body.innerHTML = "" 'Clear the default paragraph line
Set oElem = oHTMLFile.createElement("p")
Call oElem.setAttribute("id", "result")
Call oHTMLFile.body.appendChild(oElem)
Set oElem = oHTMLFile.createElement("script")
Call oElem.setAttribute("type", "text/javascript") 'Not strictly necessary as this is the default value anyways
oElem.innerText = "function regEx_Pattern_Test() {" & _
" var regEx_Pattern = " & sPattern & sPatternFlags & ";" & _
" var myInput="" & vInput & "";" & _
" document.getElementById('result').innerText = regEx_Pattern.test(myInput);" & _
"}"
Call oHTMLFile.body.appendChild(oElem)
Call oHTMLFile.parentWindow.execScript("regEx_Pattern_Test();")
'Debug.Print oHTMLFile.body.innerHTML ' For debugging
MSHTMLRegEx_Validate = CBool(oHTMLFile.getElementById("result").innerText)
Set oHTMLFile = Nothing
End Function
y se podría llamar haciendo:
? MSHTMLRegEx_Validate("/^(https?:\/\/)?((\da-z\.-)+\.(a-z\.){2,6}|(\d\.)+)((\/:?=){1}(\da-z\.-)+)*(\/\?)?$/", "igm", "
Returns => True
Para los partidos, podríamos utilizar una función como:
'---------------------------------------------------------------------------------------
' Procedure : MSHTMLRegEx_Matches
' Author : Daniel Pineault, CARDA Consultants Inc.
' Website :
' Purpose : Uses Microsoft HTML Object Library to run RegEx to extract the matches of
' the defined pattern.
' Copyright : The following is release as Attribution-ShareAlike 4.0 International
' (CC BY-SA 4.0) -
' Req'd Refs: Late Binding -> None required
' Early Binding -> Microsoft HTML Object Library (mshtml.tlb)
'
' Input Variables:
' ~~~~~~~~~~~~~~~~
' sPattern : The RegEx pattern to test the object against and extract macthes of
' sPatternFlags : The RegEx pattern flags to use
' vInput : The Object to validate against the specified pattern
' sDelimiter : Delimiter to be used to separate the matches in the returned string
' If omitted , is used
'
' Usage:
' ~~~~~~
' Extract E-mail addresses from a string
' ? MSHTMLRegEx_Matches("(a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-)+@(a-zA-Z0-9-)+(?:\.(a-zA-Z0-9-)+)", _
' "gmi", _
' "some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .")
' Returns => dani@ccc.com, marth@marth.ru, carl@hotmail.com
'
' ? MSHTMLRegEx_Matches("(a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-)+@(a-zA-Z0-9-)+(?:\.(a-zA-Z0-9-)+)", _
' "gmi", _
' "some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .", _
' "~")
' Returns => dani@ccc.com~marth@marth.ru~carl@hotmail.com
'
' Revision History:
' Rev Date(yyyy/mm/dd) Description
' **************************************************************************************
' 1 2024-03-21 Initial Release
'---------------------------------------------------------------------------------------
Public Function MSHTMLRegEx_Matches(ByVal sPattern As String, _
ByVal sPatternFlags As String, _
ByVal vInput As Variant, _
Optional sDelimiter As String = ", ") As String
'#Const HF_EarlyBind = True 'True => Early Binding / False => Late Binding
'Typically a Global Module Level Variable
#If HF_EarlyBind = True Then
Dim oHTMLFile As MSHTML.HTMLDocument
Dim oElem As MSHTML.HTMLGenericElement
Dim oLink As MSHTML.HTMLLinkElement
Dim oTable As MSHTML.HTMLTable
Dim oTr As MSHTML.HTMLTableRow
Dim oTd As MSHTML.HTMLTableCell
Set oHTMLFile = New MSHTML.HTMLDocument
#Else
Dim oHTMLFile As Object
Dim oElem As Object
Dim oLink As Object
Dim oTable As Object
Dim oTr As Object
Dim oTd As Object
Set oHTMLFile = CreateObject("HTMLFile")
#End If
oHTMLFile.body.innerHTML = "" 'Clear the default line
Set oElem = oHTMLFile.createElement("p")
Call oElem.setAttribute("id", "result")
Call oHTMLFile.body.appendChild(oElem)
Set oElem = oHTMLFile.createElement("script")
Call oElem.setAttribute("type", "text/javascript") 'Not strictly necessary as this is the default value anyways
'*** Don't use vbcrlf ... as it will erroneously place
tags in your code!
oElem.innerText = "function patternTest() {" & _
" var myPattern = '" & sPattern & "';" & _
" var myPatternFlags="" & sPatternFlags & "";" & _
" var myInput="" & vInput & "";" & _
" var myDelimiter="" & sDelimiter & "";" & _
" var reg = new RegExp(myPattern, myPatternFlags);" & _
" var output="";" & _
" var matches = myInput.match(reg);" & _
" if(matches && matches.length != 0){" & _
" for (var i = 0; i which would could use by doing:
MSHTMLRegEx_Matches("(a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-)+@(a-zA-Z0-9-)+(?:\.(a-zA-Z0-9-)+)", "gmi", "some text with dani@ccc.com and marth@marth.ru. " & Chr(10) & Chr(13) & "carl@hotmail.com Some more text .")
y que devolvería:
dani@ccc.com, marth@marth.ru, carl@hotmail.com
Conclusión
Como puede ver, podemos tener una solución relativamente sencilla para la pérdida de VBScript cuando se trata de RegEx en VBA.
Debo destacar el beneficio de usar la variable de objeto autorreparadora (SHOV) con cualquier procedimiento repetitivo. Por lo tanto, es probable que todos los procedimientos anteriores se beneficien de la implementación de SHOV. Si aún no está familiarizado con SHOV, revise el siguiente artículo para obtener más información:

Variables de objetos autorreparables¿Qué hace entonces un desarrollador cuando no puede dormir a las 3 de la mañana? ¡Decide escribir un artículo sobre variables de objeto autorreparables! ¿Qué son las variables de objeto autorreparables? En términos sencillos, son variables que son lo suficientemente inteligentes como para inicializarse una vez y conservar su valor durante toda la sesión. Si se restablecen, se reinicializarán de nuevo automáticamente. Son como variables globales con esteroides. Es solo un paso más que puede dar como desarrollador para mejorar el rendimiento general y darle a su aplicación un pequeño impulso, ¡y esto para cualquier aplicación VBA (no solo Access)! Mi primer…sigue leyendo
¡Sólo espero que msscript.ocx no sea parte de vbscript!
Además, siempre existe la posibilidad de ejecutar dicho código a través de los controles del navegador web o alguna otra biblioteca web. Incluso podríamos recurrir a la automatización de RegEx a través de PowerShell, pero no sería mi primera opción porque la automatización de PowerShell conlleva un impacto en el rendimiento. Por lo tanto, en el peor de los casos, todavía existen al menos otras posibles soluciones alternativas que podemos explorar.
Se puede hacer más con este enfoque, pero ese será un artículo para otro momento.
Algunos recursos adicionales para explorar

Expresiones regulares - JavaScript | MDNLas expresiones regulares son patrones que se utilizan para hacer coincidir combinaciones de caracteres en cadenas. En JavaScript, las expresiones regulares también son objetos. Estos patrones se utilizan con los métodos exec() y test() de RegExp, y con los métodos match(), matchAll(), replace(), replaceAll(), search() y split() de String. En este capítulo se describen las expresiones regulares de JavaScript.Historial de la página
Fecha | Resumen de Cambios |
---|---|
18-03-2024 | Versión inicial |
21-03-2024 | Se agregó la función de muestra MSHTMLRegEx_Matches a la sección Enfoque alternativo |