Регулярные множественные совпадения в 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 не может распознавать символы возврата каретки и перевода строки. Но он должен распознавать начало и конец строки.