删除html标签,但不是

时间:2016-02-02 11:32:57

标签: regex vbscript qtp hp-uft

我希望将html字符串值转换为删除了所有html标记的字符串值,除了" br",我想用换行符替换vbNewline常数)。所以我想要html中的纯文本,但保留换行符。

这看起来不是一个好的解决方案,但只要我没有带引号的字符串包含"<":

Public Function StringRemoveCharsAt (ByVal S, ByVal StartPos, ByVal Count)
    StringRemoveCharsAt=Left (S,StartPos-1) & Right (S,Len (S)-StartPos+1-Count)
End Function


Public Function StringRemoveTagsKeepNewlines (ByVal S)
    Dim R: Set R=New RegExp
    R.Global=true
    ' Matches everything, that does not start with a "<", does not contain a ">", and ends with ">" endet, as long as it is neither <br> nor <BR>:
    R.Pattern="(?!\<BR\>)(?!\<br\>)\<[^\>]*\>"
    Dim Matches: Set Matches=R.Execute (S)

    Dim Result: Result=S
    If Matches.Count > 0 Then
        Dim Index
        For Index = Matches.Count-1 to 0 step -1
            Dim Match: Set Match=Matches.Item (Index)
            Result=StringRemoveCharsAt (Result,Match.FirstIndex+1,Len (Match.Value))
        Next
    End If
    StringRemoveTagsKeepNewlines=Result
End Function

问题不在于使用正则表达式来查找标签是否是一个好主意,我确实不明白。问题是:这个代码在可靠性和速度方面是否可以轻松改进?

特别是,我没有找到一种更好的方法(使用正则表达式)而不是使用匹配所有标记的正则表达式(&#34; br&#34;除外),然后循环遍历所有匹配项,并从中删除它们串。获取所有非标记文本片段(但包括&#34; br&#34;)并不难,只需收集所有匹配并将它们附加到Result临时变量的更简单的循环?

我知道我可以更改此代码(即简化正则表达式),因此它也匹配&#34; br&#34;,然后过滤掉&#34; br&#34;在R.Execute调用后匹配循环内部。我故意离开了它,因为我认为否定正则表达式只有在它涵盖特殊情况时才值得给它带来麻烦。

P.S。:QTP / UFT测试对象中的.GetROProperty ("innertext")值完成了这项工作,但它吞下了我们想要包含的所有换行符。这是该代码出现的原始上下文:在UFT中比较预期值和实际值,保留换行符,但忽略标记,这也是我用HP UFT标记此问题的唯一原因。

这是有道理的,因为多行显示值

This is line 1
This is line 2

不得与&#34比较(和匹配);这是第1行,这是第2行&#34;但反对&#34;这是第1行\ n这是第2行&#34; (我们确实从数据文件中读取了这些值,当然,在过程中将\ n替换为vbNewline)。要求:我无法获得包含html标签或占位符/通配符的预期字符串值。

1 个答案:

答案 0 :(得分:1)

在我看来,你应该在DOM上做这个,而不是字符串。您可以根据.Object属性编写VBScript,也可以使用RunScript在JavaAcript中执行它。这里有一些我在几分钟内聚集在一起的东西供你参考,我想你做的就是你想要的。

function text(node, text)  {
    switch(node.nodeType) {
        case node.ELEMENT_NODE:
            if (node.nodeName == 'BR')
                return '\n';
            return Array.prototype.map.call(node.childNodes, function(child) {
                return text(child);
            }).join('');
        case node.TEXT_NODE:
            return node.textContent;
    }
    return '';
}