1

客观的

要搜索文本文件中的一堆行,如果找到匹配项,则将该行填充到 HTA 中显示的选项列表中。例如:如果在总共 10 行中的 5 行中找到“设置”,则所有 5 行都需要填充为“选项”

代码

    Set objFSO = CreateObject("Scripting.Filesystemobject")
Set objRegEx = New RegExp
        With objRegEx

        .Pattern    = "(\b" & "setup" & "\b)"
        .IgnoreCase = True
        .Global     = True
        End With

Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
Contents = objOpen.ReadAll


Set objMatchAll = objRegEx.Execute( Contents )
If objMatchAll.count > 0 Then

    Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
        Do Until objOpen.AtEndOfStream
            Line = objOpen.ReadLine
            Set objMatchAny = objRegEx.Execute( Line )
                        If objMatchAny.count > 0 Then
                            Set objOption = Document.createElement("OPTION")
                            objOption.Text = Line
                            objOption.Value = Line
                            ValuesList.add objOption
                            'Matched = Matched & vbNewLine & Line
                            MatchCount = MatchCount + 1

                        End If
        Loop
Else                                

    MsgBox "No results"
End If

解释

代码在文件“FileList.lst”中查找术语“setup”(当然这是在执行时动态填充的)。当找到结果时,会生成一个“选项”对象并将其添加到使用标签的 HTML 正文中的“值列表”列表中。

注 1:我生成一个“选项”对象而不是仅仅加载该行的原因是我们可以填充标签。使用该标签,因此我们可以选择任何一个搜索结果。

注意 2:创建“Contents”变量的原因是,如果根本没有匹配项,它不需要去每一行查找匹配项,这将花费更长的时间来显示该消息。

问题

该代码运行良好,测试了多达 150 个结果(结果),但是当有大量匹配项时,我的 HTA 冻结。

问题

  1. 是否可以修改现有代码以更好地执行,例如使用不同的方法来代替创建“选项”对象、生成“值列表”的替代方法?
  2. 有没有办法从 'Contents' Varialable 返回匹配的行,而不是运行两个 objRegEx 搜索结果?

更新

好的,我在没有 objOption 部分的情况下运行了我的脚本,该部分没有为我的 ValuesList 创建和添加选项,仅通过 58k 行解析正则表达式,也导致 58k 匹配,结果是 3secs ......所以看起来我需要一个替代方案来填充我的 HTA 选项列表......它无法处理那么多可供选择的选项......还有其他选择吗?我在浏览器中使用了相同的逻辑,整个浏览器都冻结了......

4

2 回答 2

3

似乎您真的只关心正则表达式是否在特定行中匹配。由于您不需要知道发生了多少匹配,也不需要实际的匹配文本,因此您可以使用该Test方法。这应该更快,因为它会在第一次匹配后停止,而且它不必构造Matches集合。出于几乎相同的原因,我也会将该Global属性保留为其默认值,但如果您只是使用该方法,我认为该属性并不重要。FalseTestGlobal

于 2013-07-23T06:25:30.480 回答
2

感谢Cheran Shunmugavel,我发现最好的方法是使用 DocumentFragments。我在我的代码中实现了这个概念,结果很棒!

新代码

Set objFSO = CreateObject("Scripting.Filesystemobject")
Set objRegEx = New RegExp
        With objRegEx

        .Pattern    = "(\b" & "setup" & "\b)"
        .IgnoreCase = True
        .Global     = True
        End With

Set objFragment = Document.createDocumentFragment()
Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
Contents = objOpen.ReadAll


Set objMatchAll = objRegEx.Execute( Contents )
If objMatchAll.count > 0 Then

    Set objOpen = objFSO.OpenTextFile ("FileList.lst", 1)
        Do Until objOpen.AtEndOfStream
            Line = objOpen.ReadLine
            Set objMatchAny = objRegEx.Execute( Line )
                        If objMatchAny.count > 0 Then
                            Set objOption = Document.createElement("OPTION")
                            objOption.innerHTML = Line
                objFragment.appendchild objOption
                            MatchCount = MatchCount + 1

                        End If
        Loop

    ViewList.appendChild objFragment.cloneNode(True)
Else                                

    MsgBox "No results"
End If

旧代码:53分23秒

新代码:31secs

于 2013-07-28T09:31:28.373 回答