【问题标题】:Using regex with positive lookbehind in VBA在 VBA 中使用正则表达式和正则表达式
【发布时间】:2017-01-18 01:21:41
【问题描述】:

这不是我完全编写的代码,有些是我从一两个站点拼凑而成的,有些是我设置的。我想要做的是使用 regex.Pattern 中定义的正则表达式函数来查看消息主题并提取一个值。这是我将在电子邮件主题中看到的内容:

新的 Linux 服务器:prod-servername-a001

到目前为止,我可以将完整的消息主题放入 Excel 文件,但是当我尝试实现正则表达式部分时,我收到错误代码 5017(我可以找到的表达式错误)并且正则表达式不是“在职的”。我的期望是脚本将提取消息主题,使用正则表达式提取值并将其放置在单元格中。我正在使用 RegEx Builder(正则表达式测试程序)来测试表达式,它在那里工作,但不是在这里。我对 VB 很陌生,所以我不知道问题是 VB 不能使用这个表达式,还是脚本在其他地方失败,而错误是另一个问题的残余。还是有更好的写法?

Sub ExportToExcel()
On Error GoTo ErrHandler

'Declarations
    Dim appExcel As Excel.Application
    Dim wkb As Excel.Workbook
    Dim wks As Excel.Worksheet
    Dim rng As Excel.Range
    Dim strSheet As String
    Dim filePath As String
    Dim strPath As String
    Dim intRowCounter As Integer
    Dim intColumnCounter As Integer
    Dim msg As Outlook.MailItem
    Dim nms As Outlook.NameSpace
    Dim fld As Outlook.MAPIFolder
    Dim itm As Object

'RegEx Declarations
    Dim result As String
    Dim allMatches As Object
    Dim regex As Object
    Set regex = CreateObject("vbscript.regexp")

    regex.Pattern = "(?<=Server: ).*"
    regex.Global = True
    regex.IgnoreCase = True


' Set the filename and path for output, requires creating the path to work
    strSheet = "outlook.xlsx"
    strPath = "D:\temp\"
    filePath = strPath & strSheet

'Debug
Debug.Print filePath

'Select export folder
    Set nms = Application.GetNamespace("MAPI")
    Set fld = nms.PickFolder

'Handle potential errors with Select Folder dialog box.
    If fld Is Nothing Then
        MsgBox "There are no mail messages to export", vbOKOnly, "Error"
        Exit Sub

    ElseIf fld.DefaultItemType <> olMailItem Then
        MsgBox "There are no mail messages to export", vbOKOnly, "Error"
        Exit Sub

    ElseIf fld.Items.Count = 0 Then
        MsgBox "There are no mail messages to export", vbOKOnly, "Error"
        Exit Sub
    End If

'Open and activate Excel workbook.
    Set appExcel = CreateObject("Excel.Application")
    appExcel.Workbooks.Open (filePath)
    Set wkb = appExcel.ActiveWorkbook
    Set wks = wkb.Sheets(1)
    wks.Activate
    appExcel.Application.Visible = True


'Copy field items in mail folder.
For Each itm In fld.Items
    intColumnCounter = 1
    Set msg = itm

    If itm.UnRead = True Then
        intRowCounter = intRowCounter + 1
        wks.Cells(1, 1).value = "Subject" 'Row 1 Column 1 (A)
        wks.Cells(1, 2).value = "Unread" 'Row 1 Column 2 (B)
        wks.Cells(1, 3).value = "Server" 'Row 1 Column 3 (C)

        Set rng = wks.Cells(intRowCounter + 1, intColumnCounter)

        If InStr(msg.Subject, "Server:") Then
        Set allMatches = regex.Execute(msg.Subject)
        rng.value = allMatches
        intColumnCounter = intColumnCounter + 1
        msg.UnRead = False                           

        Else
            rng.value = msg.Subject
            intColumnCounter = intColumnCounter + 1
            msg.UnRead = False
        End If

        Set rng = wks.Cells(intRowCounter + 1, intColumnCounter)
        rng.value = msg.UnRead
        intColumnCounter = intColumnCounter + 1
    End If

Next itm
Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing
Exit Sub


ErrHandler:

If Err.Number = 1004 Then
    MsgBox filePath & " doesn't exist", vbOKOnly, "Error"

    ElseIf Err.Number = 13 Then
        MsgBox Err.Number & ": Type Mismatch", vbOKOnly, "Error"
    ElseIf Err.Number = 438 Then
        MsgBox Err.Number & ": Object doesn't support this property or method", vbOKOnly, "Error"
    ElseIf Err.Number = 5017 Then
        MsgBox Err.Number & ": Error in expression", vbOKOnly, "Error"
    Else
        MsgBox Err.Number & ": Description: ", vbOKOnly, "Error"

End If


Set appExcel = Nothing
Set wkb = Nothing
Set wks = Nothing
Set rng = Nothing
Set msg = Nothing
Set nms = Nothing
Set fld = Nothing
Set itm = Nothing

End Sub

【问题讨论】:

  • 在VB.NET中是可以的,在VBA中不行。
  • VBA 不支持lookbehinds(stackoverflow.com/a/9154601/478656stackoverflow.com/questions/1357769/…);捕获整个 "(New Linux Server: .*)" 并字符串替换 New Linux Server: 之后什么都没有?
  • 谢谢你们!这肯定回答了我的问题。 :) 查找/替换的选项可能是一个很好的解决方案,只是希望有一个 vba 的正则表达式可以做到这一点。另外,您可以从头开始并以这种方式提取吗?我将寻找一个解决方案,看看这是否可能,但我不太了解 vb 或正则表达式,所以我必须阅读和阅读以找出你们大多数人都知道的第二天性。 ;-)

标签: regex vba excel


【解决方案1】:

VBA 正则表达式不支持lookbehinds,但在这种情况下,您不需要积极的lookbehind,您只需使用捕获组 - “Server: (.*)”` - 然后访问 Group 1 值:

Set regex = CreateObject("vbscript.regexp")
regex.Pattern = "Server: (.*)"
regex.IgnoreCase = True
Set allMatches = regex.Execute("New Linux Server: prod-servername-a001")
If allMatches.Count <> 0 Then
    rng.Value = allMatches(0).Submatches(0)
End If

这里,

  • Server: - 匹配字符串 Server: + 空格
  • (.*) - 匹配并捕获到第 1 组,除了换行符之外的零个或多个字符直到行尾。

查看更多关于capturing groups的信息。

【讨论】:

  • 抱歉,这需要很长时间才能验证,但这是我需要的帮助。谢谢!
猜你喜欢
  • 2020-09-14
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多