Регулярные множественные совпадения в VB6

У меня есть текст для сканирования, как это:

   -- FIRST BLOCK
   Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG44_CLIFOR"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   8
   End

   -- SECOND BLOCK
   Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG44_CLIFOR"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   6
   End

   -- THIRD BLOCK
   Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG16_ANAG"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   6
   End

Я хочу сопоставлять только блоки, где (MaxWidth=6).

Я делаю некоторые тесты, но что-то не так... например, с помощью этого выражения RegEx:

(Begin[\s\S]+?(MaxWidth.*=)[\s\S]+?End)

Я правильно сопоставляю блоки дерева, видимые в моем коде выше.

Затем, если я попытаюсь изменить regEx для сопоставления только блоков со значением "6" для свойства "MaxWidth":

(Begin[\s\S]+?(MaxWidth.*=   6)[\s\S]+?End)

Я правильно сопоставляю только два блока, но первый неверен. Первый матч:

Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG44_CLIFOR"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   8
   End

   -- SECOND BLOCK
   Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG44_CLIFOR"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   6
   End

Он начинается с первого "Begin" и заканчивается правильным значением свойства во втором блоке. Это неверно.

Я хочу что то (MaxWidth=6) сопоставляется внутри каждого блока Begin...End. Примерно так (ссылаясь на мой код выше):

Кулачный матч:

   Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG44_CLIFOR"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   6
   End

Второй матч:

   Begin PRJFW_EDITM.TXT_EDITM TXT_CLIFOR 
      Height          =   300
      Left            =   2685
      DBField         =   "CG16_ANAG"
      Caption         =   "Codice cliente fornitore"
      Object.Tag             =   "Codice cliente fornitore"
      MaxWidth        =   6
   End

Как я могу это сделать? Что не так в моем regEx?

Спасибо.

2 ответа

Возможно. Предполагая, что входной файл доступен в c:\test.txt , Содержит вводимый текст.

The module

Option Explicit
'requires Microsoft Scripting Runtime
Public Sub test()
    Dim fields(5) As String
    fields(0) = vbNullChar
    fields(1) = vbNullChar
    fields(2) = """CG44_CLIFOR"""
    fields(3) = vbNullChar
    fields(4) = vbNullChar
    fields(5) = "6"


    Dim fpath$, x
    fpath = "c:\test.txt"
    x = Join(GetBlock(fpath, fields), vbCrLf & vbCrLf & vbCrLf)
    MsgBox x

End Sub

Public Function GetBlock(fpath$, textArr As Variant) As Variant
    Dim results As Variant
    Dim fso As New Scripting.FileSystemObject
    Dim re As New VBScript_RegExp_55.RegExp

    If UBound(textArr) <> 5 Then
        MsgBox "Invalid data provided!"
        Exit Function
    End If

    Dim fields(5) As String
    fields(0) = "Height += +"
    fields(1) = "Left += +"
    fields(2) = "DBField += +"
    fields(3) = "Caption += +"
    fields(4) = "Object\.Tag += +"
    fields(5) = "MaxWidth += +"

    Dim p&, validPos$

    p = 0
    For p = LBound(fields) To UBound(fields)
        If textArr(p) <> vbNullChar Then
            fields(p) = fields(p) & EscapeString(CStr(textArr(p)))
            validPos = validPos & CStr(p) & "|"
        End If
    Next p


    Dim content$, result As Boolean, outText$
    content = fso.OpenTextFile(fpath).ReadAll()
    outText = vbNullChar
    With re
        .Global = True
        .IgnoreCase = True
        .MultiLine = False
        .Pattern = "--[\s\S]+?(?=--)"
        If .test(content) = True Then
            Dim m, posz
            posz = Split(validPos, "|")
            result = True
            Dim mt As Match, mts As MatchCollection
            Set mts = .Execute(content)
            For Each mt In mts
                outText = mt.Value
                Dim po
                For Each po In posz
                    If po <> "" Then
                        m = fields(CStr(po))
                        .Pattern = m
                        result = .test(outText)
                    End If
                Next po
                For Each m In fields

                Next m
                If result = True Then
                    results = results & "<cylian/>" & outText
                End If
            Next mt
        Else
            result = False
        End If
    End With
    GetBlock = Split(results, "<cylian/>", -1, vbBinaryCompare)
End Function

Private Function EscapeString(str$) As String
    'some general replaces
    Dim a$
    a = str
    a = Replace(a, """", """""")
    a = Replace(a, ".", "\.")
    a = Replace(a, "}", "\}")
    a = Replace(a, "{", "\{")
    a = Replace(a, ")", "\)")
    a = Replace(a, "(", "\(")
    a = Replace(a, "+", "\+")
    a = Replace(a, "*", "\*")
    a = Replace(a, "-", "\-")
    a = Replace(a, "\", "\\")
    a = Replace(a, "^", "\^")
    a = Replace(a, "$", "\$")
    EscapeString = a
End Function

The calling (from immediate window)

test

The outcome

Надеюсь это поможет.

Да, это возможно. Использование нескольких строк для регулярных выражений см. В этой статье пример использования нескольких строк.

VBscript не может распознавать символы возврата каретки и перевода строки. Но он должен распознавать начало и конец строки.

Другие вопросы по тегам