正则序列化

当前位置:首页>正则>正则序列化

正则序列化

' ============================================================
' 演示1: 非JIT模式序列化
' ============================================================
Sub Demo1_NonJIT_Serialization()
    On Error GoTo ErrorHandler
    
    Dim re As loquatRegExp.RegExp          ' 原始RegExp对象
    Dim serializedData As Variant  ' 序列化后的数据
    Dim re2 As loquatRegExp.RegExp         ' 反序列化后的RegExp对象
    Dim matches As Object
    Dim match As Object
    
    Debug.Print "========================================"
    Debug.Print "演示1: 非JIT模式序列化"
    Debug.Print "========================================"
    Debug.Print ""
    
    ' 步骤1: 创建并配置RegExp对象
    Debug.Print "步骤1: 创建RegExp对象..."
    Set re = CreateObject("loquat.RegExp")
    re.Pattern = "\d{4}-\d{2}-\d{2}"  ' 匹配日期格式 YYYY-MM-DD
    re.Global = True
    re.IgnoreCase = False
    
    ' 关闭JIT(非JIT模式)
    re.AutoJIT = False
    
    ' 步骤2: 编译模式(通过Test触发编译)
    Debug.Print "步骤2: 编译模式..."
    Dim testResult As Boolean
    testResult = re.test("Date: 2024-01-19")
    Debug.Print "  编译结果: " & IIf(testResult, "成功", "失败")
    Debug.Print "  是否已编译: " & re.IsCompiled
    Debug.Print "  是否JIT编译: " & re.IsJITCompiled  ' 应该是False
    Debug.Print ""
    
    ' 步骤3: 序列化编译后的模式
    Debug.Print "步骤3: 序列化..."
    'serializedData = CallByName(re, "Serialize", VbMethod)
    serializedData = re.Serialize
    Debug.Print "Serialized data type: " & VarType(serializedData) ' 应为 8209 (vbArray + vbByte)
    
    If IsArray(serializedData) Then
        Dim dataSize As Long
        dataSize = UBound(serializedData) - LBound(serializedData) + 1
        Debug.Print "  序列化成功!"
        Debug.Print "  数据大小: " & dataSize & " 字节"
    Else
        Debug.Print "  序列化失败!"
        Exit Sub
    End If
    Debug.Print ""
    
    ' 步骤4: 创建新对象并反序列化
    Debug.Print "步骤4: 反序列化..."
    Set re2 = CreateObject("loquat.RegExp")
    'CallByName re2, "Deserialize", VbMethod, serializedData
    re2.Deserialize serializedData
    
    Debug.Print "  反序列化成功!"
    Debug.Print "  是否已编译: " & re2.IsCompiled  ' 应该是True
    Debug.Print "  是否JIT编译: " & re2.IsJITCompiled  ' 应该是False
    MsgBox "  Pattern: " & re2.Pattern
    Debug.Print "  Global: " & re2.Global
    Debug.Print ""
    
    ' 步骤5: 使用反序列化后的对象进行匹配
    Debug.Print "步骤5: 使用反序列化后的对象进行匹配..."
    Dim testText As String
    testText = "Date: 2024-01-19, another date: 2023-12-25"
    
    Set matches = re2.Execute(testText)
    Debug.Print "  测试文本: " & testText
    Debug.Print "  匹配结果数量: " & matches.Count
    
    Dim i As Long
    For i = 0 To matches.Count - 1
        Set match = matches.item(i)
        Debug.Print "    匹配 " & i & ": " & match.Value & " (位置: " & match.FirstIndex & ")"
    Next i
    Debug.Print ""
    
    Debug.Print "演示1完成!" & vbCrLf
    Exit Sub
    
ErrorHandler:
    Debug.Print "错误: " & Err.Description & " (错误码: " & Err.Number & ")"
    If Not re Is Nothing Then
        Debug.Print "RegExp错误: " & re.LastError & " (代码: " & re.LastErrorCode & ")"
    End If
End Sub

' ============================================================
' 演示2: JIT模式序列化
' ============================================================
Sub Demo2_JIT_Serialization()
    On Error GoTo ErrorHandler
    
    Dim re As loquatRegExp.RegExp
    Dim serializedData As Variant
    Dim re2 As loquatRegExp.RegExp
    Dim matches As Object
    Dim match As Object
    
    Debug.Print "========================================"
    Debug.Print "演示2: JIT模式序列化"
    Debug.Print "========================================"
    Debug.Print ""
    Debug.Print "注意: JIT编译后的机器码不会序列化,"
    Debug.Print "      只序列化编译后的字节码。"
    Debug.Print "      反序列化后需要重新编译JIT。"
    Debug.Print ""
    
    ' 步骤1: 创建并配置RegExp对象
    Debug.Print "步骤1: 创建RegExp对象(启用JIT)..."
    Set re = CreateObject("loquat.RegExp")
    re.Pattern = "\b\w+@\w+\.\w+\b"  ' 匹配邮箱地址
    re.Global = True
    re.IgnoreCase = True
    re.MultiLine = True
    
    ' 启用AutoJIT
    re.AutoJIT = True
    
    ' 步骤2: 编译模式并触发JIT编译
    Debug.Print "步骤2: 编译模式并启用JIT..."
    Dim testResult As Boolean
    testResult = re.test("Contact: test@example.com")
    Debug.Print "  编译结果: " & IIf(testResult, "成功", "失败")
    Debug.Print "  是否已编译: " & re.IsCompiled
    
    ' 手动触发JIT编译
    Dim jitResult As Boolean
    jitResult = re.CompileJIT
    Debug.Print "  JIT编译结果: " & IIf(jitResult, "成功", "失败")
    Debug.Print "  是否JIT编译: " & re.IsJITCompiled  ' 应该是True
    Debug.Print ""
    
    ' 步骤3: 序列化
    Debug.Print "步骤3: 序列化..."
    Debug.Print "  注意: JIT机器码不会被序列化"
    serializedData = re.Serialize
    
    If IsArray(serializedData) Then
        Dim dataSize As Long
        dataSize = UBound(serializedData) - LBound(serializedData) + 1
        Debug.Print "  序列化成功!"
        Debug.Print "  数据大小: " & dataSize & " 字节"
    Else
        Debug.Print "  序列化失败!"
        Exit Sub
    End If
    Debug.Print ""
    
    ' 步骤4: 创建新对象并反序列化
    Debug.Print "步骤4: 反序列化..."
    Set re2 = CreateObject("loquat.RegExp")
    
    ' 启用AutoJIT,反序列化后会自动重新编译JIT
    re2.AutoJIT = True
    
    re2.Deserialize serializedData
    
    Debug.Print "  反序列化成功!"
    Debug.Print "  是否已编译: " & re2.IsCompiled  ' 应该是True
    Debug.Print "  是否JIT编译: " & re2.IsJITCompiled  ' 如果AutoJIT为True,应该会自动编译
    
    ' 如果JIT没有自动编译,手动触发
    If Not re2.IsJITCompiled Then
        Debug.Print "  手动触发JIT编译..."
        re2.CompileJIT
    End If
    Debug.Print "  最终JIT状态: " & re2.IsJITCompiled
    Debug.Print "  Pattern: " & re2.Pattern
    Debug.Print ""
    
    ' 步骤5: 使用反序列化后的对象进行匹配(使用JIT加速)
    Debug.Print "步骤5: 使用反序列化后的对象进行匹配(JIT加速)..."
    Dim testText As String
    testText = "Emails: admin@example.com, user@test.org, invalid-email"
    
    Set matches = re2.Execute(testText)
    Debug.Print "  测试文本: " & testText
    Debug.Print "  匹配结果数量: " & matches.Count
    
    Dim i As Long
    For i = 0 To matches.Count - 1
        Set match = matches.item(i)
        Debug.Print "    邮箱 " & (i + 1) & ": " & match.Value & " (位置: " & match.FirstIndex & ")"
    Next i
    Debug.Print ""
    
    ' 步骤6: 性能测试(JIT加速效果)
    Debug.Print "步骤6: 性能测试(匹配1000次)..."
    Dim startTime As Double
    Dim endTime As Double
    Dim j As Long
    
    startTime = Timer
    For j = 1 To 1000
        Set matches = re2.Execute(testText)
    Next j
    endTime = Timer
    
    Dim elapsedMs As Double
    elapsedMs = (endTime - startTime) * 1000
    Debug.Print "  1000次匹配耗时: " & Format(elapsedMs, "0.00") & " 毫秒"
    Debug.Print "  平均每次: " & Format(elapsedMs / 1000, "0.000") & " 毫秒"
    Debug.Print ""
    
    Debug.Print "演示2完成!" & vbCrLf
    Exit Sub
    
ErrorHandler:
    Debug.Print "错误: " & Err.Description & " (错误码: " & Err.Number & ")"
    If Not re Is Nothing Then
        Debug.Print "RegExp错误: " & re.LastError & " (代码: " & re.LastErrorCode & ")"
    End If
End Sub