2

我正在尝试在 VBScript 中使用 Regex 将具有“候选人”类的 HTML 标记替换为文本“PLACEHOLDER”。但是,它并不总是有效。

<[^\>]*class=""[^\>]*candidate[^\>]*""[^\>]*>([\s\S]*?)</[^\>]*>

Flags: IgnoreCase = True, Multiline = True, Global = True

问题是我不确定哪种类型的 HTML 标记将包含此类(例如,它可能是 < div > 标记或 < p > 标记)。其次,正则表达式不适用于内部 HTML 标记。

主题 HTML:

<div class="outer">
<div class="normal">
<p><strong><em>Test</em></strong></p>
</div>
<div class="candidate">
<p>Test 1:</p>
<ul>
    <li>Test 2</li>
    <li>Test 3 </li>
    <li>Test 4 </li>
</ul>
<p>Test 5</p>
</div>
<p>Test 6</p>
<div class="normal">
<p><strong>Test 7</strong></p>
</div>
</div>

预期的:

<div class="outer">
<div class="normal">
<p><strong><em>Test</em></strong></p>
</div>
<div class="candidate">
PLACEHOLDER
</div>
<p>Test 6</p>
<div class="normal">
<p><strong>Test 7</strong></p>
</div>
</div>

实际的:

<div class="outer">
<div class="normal">
<p><strong><em>Test</em></strong></p>
</div>
<div class="candidate">
PLACEHOLDER
    <li>Test 2</li>
    <li>Test 3 </li>
    <li>Test 4 </li>
</ul>
<p>Test 5</p>
</div>
<p>Test 6</p>
<div class="normal">
<p><strong>Test 7</strong></p>
</div>
</div>

相同的 HTML 标记也可能具有相同类型但不同类的内部标记,这些标记目前偶尔会起作用。

例如:

<div class="candidate">Test<div class="normal">Test</div></div>

任何帮助将不胜感激。

4

1 回答 1

3

必须是正则表达式吗?使用MSHTML(或任何其他 HTML 解析器),这项任务非常简单。在此示例中,我将您的主题 HTML 放在一个名为“test.htm”的文件中:

Option Explicit

Const ForReading = 1

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
Dim inFile
Set inFile = fso.OpenTextFile("test.htm", ForReading)

Dim html
Set html = CreateObject("htmlfile")
html.write inFile.ReadAll()
inFile.Close

Dim allElements
Set allElements = html.getElementsByTagName("*")

Dim el
For Each el in allElements
    If (HasClass(el, "candidate")) Then
        el.innerText = "PLACEHOLDER"
    End If
Next

WScript.Echo html.body.outerHtml

' Takes into account the fact that the HTML "class" attribute can
' contain multiple whitespace-delimited classes
Function HasClass(el, className)
    Dim re
    Set re = New RegExp

    re.Pattern = "\b" & className & "\b"
    HasClass = re.Test(el.className)
End Function
于 2012-10-15T06:42:17.037 回答