【问题标题】:How to find a multiline match with RegEx in a text file using VBA?如何使用 VBA 在文本文件中查找与 RegEx 的多行匹配?
【发布时间】:2019-08-08 14:40:31
【问题描述】:

我有一个 .txt 报告,我需要提取在整个文件中多次出现的某些元素(使用 RegEx 组)。为了捕获我需要的特定元素,我必须将文本行中的文本与模式匹配,然后向前看,看看下一行是否匹配不同的模式。如果两者都为真,则将这些组的值返回到一个数组中。

我正在使用 VBA 和 RegExp 库在 Excel 2013 中工作。我能够在 RegEx 中编写多行模式以及命名组中需要的所有相关字段。我能够打开一个文本文件并将数据加载到一个字符串中。我不能同时做的就是两者。我只能针对一种模式识别一行文本。

编辑:这里是一些从原始来源编辑的示例文本

                                                     DAILY CONTROL REPORT                                    WORK OF: 08/07/19  
                                                     ACQUIRING                                                     PAGE:    1   
CUSTOMER           : ACME CORP                                                                                                      
CUSTOMER ID        : 0000000001                                                                                                     
Other miscellaneous data

                                                     DAILY CONTROL REPORT                                    WORK OF: 08/07/19  
                                                     ISSUING                                                       PAGE:    2   
CUSTOMER           : ACME CORP                                                                                                      
CUSTOMER ID        : 0000000001                                                                                                     
Other miscellaneous data

                                                     DAILY CONTROL REPORT                                    WORK OF: 08/07/19  
                                                     NET SETTLEMENT SUMMARY                                        PAGE:    3   
CUSTOMER           : ACME CORP                                                                                                      
CUSTOMER ID        : 0000000001                                                                                                     
Other miscellaneous data

                                                     DAILY CONTROL REPORT                                    WORK OF: 08/07/19  
                                                     ACQUIRING                                                     PAGE:    4   
CUSTOMER           : ACME INC                                                                                                       
CUSTOMER ID        : 0000000002                                                                                                     
Other miscellaneous data

                                                     DAILY CONTROL REPORT                                    WORK OF: 08/07/19  
                                                     ISSUING                                                       PAGE:    5   
CUSTOMER           : ACME INC                                                                                                       
CUSTOMER ID        : 0000000002                                                                                                     
Other miscellaneous data

                                                     DAILY CONTROL REPORT                                    WORK OF: 08/07/19  
                                                     NET SETTLEMENT SUMMARY                                        PAGE:    6   
CUSTOMER           : ACME INC                                                                                                       
CUSTOMER ID        : 0000000002                                                                                                     
Other miscellaneous data
Dim rgx As Object
Set rgx = CreateObject("VBScript.RegExp")
Dim MyFolder As String
Dim MyFile As String
Dim TextLine As String
Dim strPattern As String
Dim strReport As String
Dim MyArray() As Variant
Dim i As Integer

MyFolder = "C:\Reports\Samples\"
MyFile = "MySampleFile.txt"
strPattern = "WORK OF: (?<WORKOF>\d\d\/\d\d\/\d\d)\s+\n\s+NET SETTLEMENT 
SUMMARY.+\n.{22}(?<NAME>.+\b)\s+\n.{22}(?<NUM>\d+)\s+\n"

With rgx
.Global = True
.MultiLine = True
.IgnoreCase = False
.Pattern = strPattern
End With

Open (MyFolder & MyFile) For Input As #1
Do Until EOF(1)
Line Input #1, TextLine
strReport = strReport & TextLine
Loop
Close #1

i = 0

If rgx.Test(strReport) Then
ReDim Preserve MyArray(0 to i, 0 to 2)
MyArray(i, 0) = rgx.Replace(strReport, WORKOF)  
MyArray(i, 1) = rgx.Replace(strReport, NAME)    
MyArray(i, 2) = rgx.Replace(strReport, NUM) 
i = i +1
End IF

我知道这段代码有一些问题: 1.strReport字符串每行末尾不包含CrLF 2. rgx.Test 语句应该循环通过 strReport 寻找 多行匹配,但它的编写方式总是无法通过测试。 3. 我不确定如何填充数组,但最终会包含数百条记录,每条记录有 3 个值 {WORKOF, NAME, NUM} 4. WORKOF 在每页的页眉中,但字符串“NET SETTLEMENT Summary”仅在每 3 或 4 页出现一次。这就是我要捕获的信息所在的位置。

【问题讨论】:

  • 我们需要查看来自您的MySampleFile.txt 的数据,以评估您的正则表达式正在做什么。加上给定示例数据,包括您希望从正则表达式中获得的确切结果。
  • 当您读取文件时,您实际上是在去除行分隔符 - 在构建 strReport 时添加它们。或者不要逐行阅读:codevba.com/office/read_text_file_into_string_variable.htm 至少在 Windows 上,行分隔符通常是 vbCRLf (\r\n)
  • 我不知道 VBA 支持命名组。
  • 实际上,VBA 正则表达式引擎支持命名捕获组。刚刚签入 MS Excel 2013。还有 2。 rgx.Test 语句应该循环遍历 strReport 以寻找多行匹配,但它的编写方式总是会导致测试失败。 证明这一点。

标签: regex vba


【解决方案1】:

我没有您的文本文件,但我创建了一个包含以下内容的测试输入文件:

工作时间:56 年 12 月 34 日净结算摘要名称 1 789

工作时间:01/23/45 净结算摘要名称1 6789

我可以用以下代码匹配模式:

Option Explicit

' Include: Tools > References > Microsoft VBScript Regular Expressions 5.5

Public Sub FindPatternInTextFile_Test()
    Dim varResult As Variant: varResult = FindPatternInTextFile("C:\Reports\Samples\MySampleFile.txt", "WORK OF: (\d\d\/\d\d\/\d\d)\s+NET SETTLEMENT SUMMARY\s+(.+\b)\s+(\d+)")
End Sub

Public Function FindPatternInTextFile(strPath As String, strPattern As String) As Variant
    Dim strContent As String: strContent = ReadWholeTextFile(strPath)
    Dim rgxPattern As RegExp: Set rgxPattern = CreateRegex(strPattern)
    Dim mtcFound As MatchCollection: Set mtcFound = rgxPattern.Execute(strContent)
    If 0 < mtcFound.Count Then
        Dim strResult() As String: ReDim strResult(0 To mtcFound.Count - 1, 0 To 2)
        Dim i As Long: For i = 0 To mtcFound.Count - 1
            strResult(i, 0) = mtcFound(i).SubMatches(0)
            strResult(i, 1) = mtcFound(i).SubMatches(1)
            strResult(i, 2) = mtcFound(i).SubMatches(2)
        Next i
        FindPatternInTextFile = strResult
    Else
        FindPatternInTextFile = vbNullString
    End If
End Function

Public Function ReadWholeTextFile(strPath As String) As String
    Dim strResult As String: strResult = vbNullString
    Open strPath For Input As #1
    Do Until EOF(1)
        Dim strLine As String: strLine = vbNullString
        Line Input #1, strLine
        strResult = strResult & strLine & vbCrLf
    Loop
    Close #1
    ReadWholeTextFile = strResult
End Function

Public Function CreateRegex(strPattern As String) As RegExp
    Dim rgxResult As RegExp: Set rgxResult = New RegExp
    With rgxResult
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = strPattern
    End With
    Set CreateRegex = rgxResult
End Function

您必须根据您的实际数据自定义正则表达式模式。

【讨论】:

    猜你喜欢
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多