2

我有这样的文本要扫描:

   -- 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)

我正确匹配了上面代码中可见的树块。

然后,如果我尝试修改正则表达式以仅匹配“MaxWidth”属性的值为“6”的块:

(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

它从第一个“开始”开始,并以第二个块中的正确属性值结束。那是错误的。

我希望 ( 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

我怎样才能做到这一点?我的正则表达式有什么问题?

谢谢你。

4

2 回答 2

3

这是可能的。假设输入文件位于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

在此处输入图像描述

希望这可以帮助。

于 2012-09-10T08:45:54.267 回答
1

是的,有可能。对正则表达式使用多行选项,请参阅本文以获取有关如何使用多行的示例。

VBscript 无法识别回车和换行控制字符。但它应该识别行的开头和行的结尾。

于 2012-09-10T07:58:19.967 回答