问题评估&在Excel VBA中迭代正则表达式

时间:2017-05-06 17:17:06

标签: vba excel-vba iteration excel

我的目标是将我正在运行的Python脚本逻辑转换为Excel VBA宏。由于我不熟悉VBA,因此我遇到了一些在Python中工作但不在此处的构造问题。作为背景,我的Python脚本读取Word文档,要求用户输入从包含正则表达式片段的预制变量创建模式,在docx上执行正则表达式并将这些结果返回到Excel单元格。以下代码是我目前使用Excel VBA的问题部分:

patterninput = InputBox("a1 = Title" & vbNewLine & "a2 = First Name" & vbNewLine & "a3 = Last Name" & vbNewLine & "b = Address" & vbNewLine & "c = Town, State Zip" & vbNewLine & "x = Line Omit", "Step #3: Enter Pattern")
            Dim x As String
            Dim a1 As String
            Dim a2 As String
            Dim a3 As String
            Dim b As String
            Dim c As String
            x = "(?:.+)\s+"
            a1 = "([\w\.]+)\s+"
            a2 = "(\w+)\s+"
            a3 = "(.+)[\s\n]+"
            b = "(\d+\s.+)[\s\n]+"
            c = "(.+)"
    pattern = keyword & "[\s\n]+" & Application.Evaluate(patterninput)

    Dim objMatches As MatchCollection

    With regEx
        .Global = False
        .MultiLine = True
        .IgnoreCase = False
        .pattern = pattern
    End With

    Set objMatches = regEx.Execute(strInput)
    Dim row As Long
    Dim SubMatches As Variant
    row = .Rows.Count + 1
    For Each SubMatches In objMatches
        Cells(row, 1).Value = objMatches(0).SubMatches(0)
        Cells(row, 2).Value = objMatches(0).SubMatches(1)
        Cells(row, 3).Value = objMatches(0).SubMatches(2)
        Cells(row, 4).Value = objMatches(0).SubMatches(3)
        Cells(row, 5).Value = objMatches(0).SubMatches(4)
        row = row + 1
    Next

我的第一个问题是我似乎无法评估模式输入,就像eval()在Python中如何工作一样,因此会导致错误。有没有一种方法可以评估和连接用户输入,同时为模式变量分配适当的片段?

如果我省略这篇文章并为演示目的硬编码模式,我会遇到第二个更重要的问题。我希望正则表达式找到一个匹配,然后取每个子匹配并将它放入同一行中的5个单独的列中(我希望它从最大行+ 1开始;基本上是第一个未写入的行)。一旦完成,我希望它移动到下一个匹配,执行相同的操作,但在下一行(因此行=行+ 1,因为VBA显然不能行+ = 1)。但是,它现在的工作方式,它正确地执行前两列,但然后将其余的文本(和可行的匹配)抛出到第三列并完成。我需要它来迭代,但我似乎无法让它工作。以下是我正在使用的演示文本"真诚"是关键字:

Dear Sir,

Hello

Sincerely,

Mr. Thomas Dahlmer
46 Alpine Street
Evanston, Il 60201

Dear Sir,

Hello

Sincerely,

Mr. Robert Thomas
1104 Madison Avenue
New York, NY 10021

任何帮助都将非常感谢,希望我能从中学习并更好地熟悉Excel VBA。谢谢!

1 个答案:

答案 0 :(得分:1)

您必须将信件的正文文本放入我的str变量中;为了演示目的,我只是将示例文本放入A2(实际上,A2:A17合并)。有很多关于将文本文件转换为此站点上的字符串变量的示例。

这使用Instr和Split来避免使用正则表达式模式。 TBPH,我对多线全局正则表达式模式并不擅长。

Option Explicit

Sub wqreqwq()
    Dim b As Long, e As Long
    Dim str As String, sal As String, con As String
    Dim info As Variant

    With Worksheets("sheet6")
        ReDim info(4)
        sal = "sincerely," & vbLf & vbLf
        str = Replace(.Cells(2, "A").Value2, vbCrLf, vbLf) & vbLf & vbLf

        b = InStr(1, str, sal, vbTextCompare)
        Do While CBool(b)
            b = b + Len(sal)
            e = InStr(b, str, vbLf & vbLf, vbTextCompare)
            'b = InStr(e + 2, str, sal, vbTextCompare)

            con = Mid(str, b, e - b)
            info = Split(con, vbLf)
            ReDim Preserve info(4)
            info(3) = Split(info(2), Chr(44) & Chr(32))(1)
            info(2) = Split(info(2), Chr(44) & Chr(32))(0)
            info(4) = Split(info(3), Chr(32))(1)
            info(3) = Split(info(3), Chr(32))(0)
            .Cells(.Rows.count, "C").End(xlUp).Offset(1, 0).Resize(1, 5) = info

            b = InStr(e, str, sal, vbTextCompare)
        Loop

    End With

End Sub

我已将邮政编码保留为文本 - 看起来像一个数字。通常,我将etxt转换为数字并使用自定义数字格式,如[>99999]00000-0000;00000;[red]@,显示zips-as-true-numbers,同时允许zips和zip + 4' s。任何拒绝成为真实数字的值都会以红色字体显示,以便让您知道失败。

enter image description here