0

所以我今天刚让我的网站启动服务器,我认为这个功能是罪魁祸首。谁能告诉我问题是什么?我似乎无法弄清楚:

Public Function CleanText(ByVal str As String) As String    
'removes HTML tags and other characters that title tags and descriptions don't like
    If Not String.IsNullOrEmpty(str) Then
        'mini db of extended tags to get rid of
        Dim indexChars() As String = {"<a", "<img", "<input type=""hidden"" name=""tax""", "<input type=""hidden"" name=""handling""", "<span", "<p", "<ul", "<div", "<embed", "<object", "<param"}

        For i As Integer = 0 To indexChars.GetUpperBound(0) 'loop through indexchars array
            Dim indexOfInput As Integer = 0
            Do 'get rid of links
                indexOfInput = str.IndexOf(indexChars(i)) 'find instance of indexChar
                If indexOfInput <> -1 Then
                    Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput) + 1
                    Dim indexRightBracket As Integer = str.IndexOf(">", indexOfInput) + 1
                    'check to make sure a right bracket hasn't been left off a tag
                    If indexNextLeftBracket > indexRightBracket Then 'normal case
                        str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)
                    Else
                        'add the right bracket right before the next left bracket, just remove everything
                        'in the bad tag
                        str = str.Insert(indexNextLeftBracket - 1, ">")
                        indexRightBracket = str.IndexOf(">", indexOfInput) + 1
                        str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)
                    End If
                End If
            Loop Until indexOfInput = -1
        Next
    End If
    Return str
End Function
4

7 回答 7

5

这样的事情不会更简单吗?(好的,我知道它与发布的代码不同):

public string StripHTMLTags(string text)
{
    return Regex.Replace(text, @"<(.|\n)*?>", string.Empty);
}

(转换为 VB.NET 应该很简单!)

注意:如果您经常运行此程序,您可以对Regex.

一种是使用需要稍微重写的预编译表达式。

第二种是使用非捕获形式的正则表达式;.NET 正则表达式实现 (?:) 语法,它允许进行分组,而不会导致捕获的文本被记住为反向引用而导致性能损失。使用此语法,上述正则表达式可以更改为:

@"<(?:.|\n)*?>"
于 2009-05-05T02:31:49.403 回答
3

这行也是错误的:

Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput) + 1

保证总是将 indexNextLeftBracket 设置为等于 indexOfInput,因为此时 indexOfInput 所指位置处的字符已经始终是“<”。改为这样做:

Dim indexNextLeftBracket As Integer = str.IndexOf("<", indexOfInput+1) + 1

并且还要在 if 语句中添加一个子句,以确保您的字符串足够长以用于该表达式。

最后,正如其他人所说,如果你能让它工作,这段代码将是一个难以维护的野兽。最好寻找另一种解决方案,例如正则表达式,甚至只是将所有 '<' 替换为&lt;.

于 2009-05-05T02:48:49.610 回答
1

除了其他好的答案之外,您可能会阅读一些关于循环不变量的内容。拉出和放回你检查的绳子以终止你的循环应该引发各种警钟。:)

于 2009-05-05T02:36:20.453 回答
0

只是一个猜测,但这就像罪魁祸首吗?indexOfInput = str.IndexOf(indexChars(i)) '找到 indexChar 的实例

根据Microsoft 文档,返回值 - 如果找到该字符串,则返回 value 的索引位置,否则返回 -1。如果 value 为 Empty,则返回值为 0。

所以也许 indexOfInput 被设置为 0?

于 2009-05-05T02:11:36.080 回答
0

如果你的代码试图清理字符串会发生什么<a

当我读到它时,它发现 indexChar 在位置 0,但是 indexNextLeftBracket 和 indexRightBracket 都等于 0,你进入 else 条件,然后你在位置 -1 处插入一个“>”,它可能会在开头插入,给你字符串><a。新的 indexRightBracket 然后变为 0,因此您从位置 0 删除 0 个字符,留下><a. 然后<a代码再次在代码中找到 ,然后您将进入具有无限内存消耗循环的竞赛。

即使我错了,您也需要让自己进行一些单元测试,以确保这些边缘情况正常工作。如果我不在基地,那也应该可以帮助您找到实际的循环代码。

不过一般来说,即使你修复了这个特定的错误,它也永远不会变得非常健壮。解析 HTML 很困难,而且 HTML 黑名单总是会有漏洞。例如,如果我真的想在其中添加一个<input type="hidden" name="tax"标签,我将其编写为<input name="tax" type="hidden",您的代码将忽略它。你最好的办法是让一个实际的 HTML 解析器参与进来,并且只允许你真正想要的(非常小的)标签子集。或者更好的是,使用其他形式的标记,并去除所有 HTML 标记(再次使用具有某种描述的真实 HTML 解析器)。

于 2009-05-05T02:25:37.547 回答
0

我必须通过一个真正的编译器运行它,但是 mindpiler 告诉我该str = str.Remove(indexOfInput, indexRightBracket - indexOfInput)行正在重新生成一个无效的标签,这样当你再次循环时它会发现同样的错误“修复”它,再试一次,发现错误“修复”它,等等。

FWIW 是一段从字符串中删除不需要的 HTML 标记的代码片段(它在 C# 中,但概念可以翻译)

public static string RemoveTags( string html, params string[] allowList )
{
    if( html == null ) return null;
    Regex regex = new Regex( @"(?<Tag><(?<TagName>[a-z/]+)\S*?[^<]*?>)",
                             RegexOptions.Compiled | 
                             RegexOptions.IgnoreCase | 
                             RegexOptions.Multiline );
    return regex.Replace( 
                   html, 
                   new MatchEvaluator( 
                       new TagMatchEvaluator( allowList ).Replace ) );
}

MatchEvaluator 类

private class TagMatchEvaluator
{
    private readonly ArrayList _allowed = null;

    public TagMatchEvaluator( string[] allowList ) 
    { 
        _allowed = new ArrayList( allowList ); 
    }

    public string Replace( Match match )
    {
        if( _allowed.Contains( match.Groups[ "TagName" ].Value ) )
            return match.Value;
        return "";
    }
}
于 2009-05-05T02:27:35.420 回答
0

这似乎不适用于简单的<a<a<a案例,甚至<a>Test</a>. 你有没有测试过这个?

就个人而言,我讨厌这样的字符串解析 - 所以我什至不会尝试找出你的错误在哪里。它需要一个调试器,而且比我愿意投入的更令人头疼。

于 2009-05-05T02:33:12.690 回答