سؤال

وهكذا أنا فقط حصلت على موقعي انطلقت الخادم اليوم، وأعتقد أن هذه هي وظيفة الجاني. يمكن لأحد أن يقول لي ما هي المشكلة؟ أنا لا يمكن أن يبدو لأنها من أصل الرقم:

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
هل كانت مفيدة؟

المحلول

ولن شيئا من هذا القبيل تكون أبسط؟ (حسنا، أنا أعلم أنها ليست متطابقة إلى رمز مرسل):

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

و(التحويل إلى VB.NET يجب أن تكون تافهة!)

ملحوظة: إذا كنت تقوم بتشغيل هذا في كثير من الأحيان، وهناك نوعان من تحسينات الأداء التي يمكن أن تجعل لRegex.

واحد هو استخدام تعبير جمعت قبل التي تتطلب قليلا-كتابة إعادة.

والثاني هو لاستخدام نموذج غير التقاط للتعبير منتظم؛ التعابير العادية. NET على تنفيذ (؟ :) لغوي، والذي يسمح للتجمع الذي يتعين القيام به دون تكبد عقوبة أداء النص القبض يجري يذكر بوصفه backreference. استخدام هذا النحو، يمكن تغييره التعبير العادي أعلاه إلى:

@"<(?:.|\n)*?>"

نصائح أخرى

وهذا الخط هو أيضا خطأ:

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

وانها مضمونة لتحديد دائما indexNextLeftBracket يساوي indexOfInput، لأنه في هذه النقطة الحرف في الموقف الذي أشار إليه indexOfInput هو دائما بالفعل '<'. هل هذا بدلا من ذلك:

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

وأيضا إضافة فقرة إلى بيان إذا للتأكد من سلسلة الخاص بك طويلة بما فيه الكفاية لهذا التعبير.

وأخيرا، وكما قال آخرون سوف هذا الرمز أن يكون وحشا للحفاظ على، إذا كان يمكنك الحصول على عمل على الإطلاق. أفضل للبحث عن حل آخر، مثل التعابير المنطقية أو حتى مجرد استبدال جميع '<' مع &lt;.

وبالإضافة إلى أجوبة أخرى جيدة، قد تقرأ قليلا على ل بعض الشيء. وسحب ووضع مرة أخرى الاشياء في السلسلة التي تحقق لإنهاء حلقة الخاص بك ينبغي أن ينطلق كل أنواع أجراس الإنذار. :)

ومجرد تخمين، ولكن هل هذا مثل الجاني؟ indexOfInput = str.IndexOf (indexChars (ط)) تجد مثيل indexChar

مستندات مايكروسوفت ، عودة القيمة - موقف مؤشر قيمة إذا تم العثور على هذه السلسلة، أو -1 إذا لم يكن. إذا كانت القيمة فارغة، قيمة الإرجاع هي 0.

وهكذا ربما يجري إنشاء indexOfInput 0؟

وماذا يحدث إذا التعليمات البرمجية يحاول تنظيف <a سلسلة؟

وكما قرأت ذلك، فإنه يجد indexChar في موقف 0، ولكن بعد ذلك indexNextLeftBracket وindexRightBracket كلا يساوي 0، يمكنك الوقوع في حالة آخر، ثم قمت بإدراج ">" في موقف -1، والتي سوف تضاف يفترض في بداية، مما يتيح لك ><a السلسلة. وindexRightBracket جديدة ثم يصبح 0، لذلك قمت بحذفها من موقف 0 ل 0 حرفا، ويترك لك مع ><a. ثم يجد رمز <a في الرمز مرة أخرى، وكنت خارج السباقات مع حلقة تستغرق والذاكرة لا نهائية.

وحتى لو كنت مخطئا، تحتاج إلى الحصول على نفسك بعض الاختبارات وحدة لطمأنة نفسك أن هذه الحالات حافة تعمل بشكل صحيح. وينبغي أن تساعد أيضا على العثور على رمز حلقات الفعلي إذا أنا خارج القاعدة.

وبصفة عامة على الرغم من، حتى لو كنت إصلاح هذا الخطأ بعينه، وانها لن تكون قوية جدا. تحليل HTML من الصعب، والقوائم السوداء HTML دائما ستكون لدينا الثقوب. على سبيل المثال، إذا كنت حقا ترغب في الحصول على علامة <input type="hidden" name="tax" في، وأنا أكتب فقط أنها <input name="tax" type="hidden" وسوف التعليمات البرمجية تجاهله. لديك أفضل رهان هو الحصول على محلل HTML الفعلي المعنية، وفقط تسمح فرعية (صغيرة جدا) من العلامات التي تريد فعلا. أو حتى أفضل، واستخدام بعض شكل آخر من أشكال الترميز، وتجريد كل علامات HTML (مرة أخرى باستخدام HTML محلل الحقيقي لبعض الوصف).

وكنت قد لتشغيله من خلال مترجم الحقيقي ولكن 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 "";
    }
}

وهذا لا يبدو للعمل من أجل قضية <a<a<a التبسيط، أو حتى <a>Test</a>. هل اختبار هذا على الإطلاق؟

وشخصيا، أنا أكره سلسلة تحليل مثل هذا - لذلك أنا لن أحاول حتى معرفة أين الخطأ هو. انها تريد تتطلب مصحح، وأكثر من ذلك الصداع من أنا على استعداد لوضع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top