4 Stimmen

Warum wird eine linke Klammer in dieser Regex ausgeblendet?

Ich verwende einen HTML-Sanitizing-Whitelist-Code, den ich hier gefunden habe:
http://refactormycode.com/codes/333-sanitize-html

Ich musste das "font"-Tag als zusätzliches Tag hinzufügen, um es abzugleichen, also habe ich versucht, diese Bedingung nach der <img Tag-Check

if (tagname.StartsWith("<font"))
{
    // detailed <font> tag checking
    // Non-escaped expression (for testing in a Regex editor app)
    // ^<font(\s*size="\d{1}")?(\s*color="((#[0-9a-f]{6})|(#[0-9a-f]{3})|red|green|blue|black|white)")?(\s*face="(Arial|Courier New|Garamond|Georgia|Tahoma|Verdana)")?\s*?>$
    if (!IsMatch(tagname, @"<font
                            (\s*size=""\d{1}"")?
                            (\s*color=""((#[0-9a-f]{6})|(#[0-9a-f]{3})|red|green|blue|black|white)"")?
                            (\s*face=""(Arial|Courier New|Garamond|Georgia|Tahoma|Verdana)"")?
                             \s*?>"))
    {
        html = html.Remove(tag.Index, tag.Length);
    }
}

Abgesehen von der obigen Bedingung ist mein Code fast identisch mit dem Code auf der Seite, auf die ich verlinkt habe. Wenn ich versuche, dies in C# zu testen, wird eine Ausnahme ausgelöst, die besagt, dass " Not enough )'s ". Ich habe die Klammern mehrmals gezählt, und ich habe den Ausdruck durch ein paar Online-Javascript-basierte Regex-Tester laufen lassen, und keiner von ihnen scheint mir irgendwelche Probleme zu melden.

Übersehe ich etwas in meiner Regex, das dazu führt, dass eine Klammer ausbricht? Was muss ich tun, um das zu beheben?

UPDATE
Nach vielen Versuchen und Irrtümern erinnerte ich mich daran, dass die # Zeichen ist ein Kommentar in Regexen. Der Schlüssel zur Lösung dieses Problems ist die Escape-Funktion für das # Charakter. Für den Fall, dass jemand anderes auf das gleiche Problem stößt, habe ich meine Lösung beigefügt (ich habe einfach das # Zeichen)

if (tagname.StartsWith("<font"))
{
    // detailed <font> tag checking
    // Non-escaped expression (for testing in a Regex editor app)
    // ^<font(\s*size="\d{1}")?(\s*color="((#[0-9a-f]{6})|(#[0-9a-f]{3})|red|green|blue|black|white)")?(\s*face="(Arial|Courier New|Garamond|Georgia|Tahoma|Verdana)")?\s*?>$
    if (!IsMatch(tagname, @"<font
                            (\s*size=""\d{1}"")?
                            (\s*color=""((\#[0-9a-f]{6})|(\#[0-9a-f]{3})|red|green|blue|black|white)"")?
                            (\s*face=""(Arial|Courier\sNew|Garamond|Georgia|Tahoma|Verdana)"")?
                             \s*?>"))
    {
        html = html.Remove(tag.Index, tag.Length);
    }
}

0 Stimmen

Ihr Update gilt nur, wenn die IgnorePatternWhitespace-Option angegeben ist ... die in der IsMatch-Code, den ich gefragt, ohne eine Antwort ... dh Sie haben nicht zeigen uns den Code, der das Problem verursacht.

0 Stimmen

Nebenbei bemerkt: Ihr Regex passt nicht zu einem Font-Tag, bei dem die Attribute in einer anderen Reihenfolge stehen, wie <font color="red" size="2">.

0 Stimmen

Ich habe kein Problem damit, dass die Attribute nicht in einer anderen Reihenfolge abgeglichen werden. Das HTML-Editor-Steuerelement, das ich verwende, erzeugt das <font>-Tag nur in der Reihenfolge, für die ich teste.

5voto

Christian C. Salvadó Punkte 763569

Ihre IsMatch-Methode verwendet die Option RegexOptions.IgnorePatternWhitespace die es Ihnen erlaubt, Kommentare in die regulären Ausdrücke einzufügen. Sie müssen also das Chatzeichen # auslassen, da es sonst als Kommentar interpretiert wird.

if (!IsMatch(tagname,@"<font(\s*size=""\d{1}"")?
    (\s*color=""((\#[0-9a-f]{6})|(\#[0-9a-f]{3})|red|green|blue|black|white)"")?
    (\s*face=""(Arial|Courier New|Garamond|Georgia|Tahoma|Verdana)"")?
    \s?>"))
{
    html = html.Remove(tag.Index, tag.Length);
}

2voto

Robert Gamble Punkte 101657

Ich kann keinen offensichtlichen Fehler in der Regex erkennen. Ich würde versuchen, das Problem durch Entfernen von Teilen der Regex zu isolieren, bis das Problem verschwindet, und mich dann auf den Teil konzentrieren, der das Problem verursacht.

0 Stimmen

Ich bin mir nicht sicher, ob es etwas mit der Regex zu tun hat - bei mir funktioniert es einwandfrei

1voto

Marc Gravell Punkte 970173

Bei mir funktioniert es einwandfrei... welche Version des .NET-Frameworks verwenden Sie, und wie lautet die genau Ausnahme?

Außerdem - was macht Sie IsMatch Methode aussehen? Ist dies nur eine Durchleitung zu Regex.IsMatch ?

[Update] Das Problem ist, dass der OP-Beispielcode nicht zeigen, dass sie die IgnorePatternWhitespace Regex-Option verwenden; mit dieser Option funktioniert es nicht; ohne diese Option (d.h. wie vorgestellt) der Code ist in Ordnung.

1voto

Dan Finucane Punkte 1497

Chris Sells herunterladen Regex-Designer . Es ist ein großartiges kostenloses Tool zum Testen von .NET-Regexen.

Ich bin nicht sicher, dass diese Regex wird tun, was Sie wollen, weil es auf die Reihenfolge der Attribute übereinstimmen, was Sie in der Regex haben abhängt. Wenn zum Beispiel face="Arial" vorausgegangen ist size="5" dann face= nicht übereinstimmen würden.

In Ihrer Regex gibt es einige Probleme mit dem Escaping. Sie müssen Ihre " con \ Sie müssen Ihrem # con \ Sie müssen Folgendes verwenden \s in Courier New anstelle des Leerzeichens. Sie müssen die RegexOptions.IgnorePatternWhitespace y RegexOptions.IgnoreCase options .

<font
(\s+size=\"\d{1}\")?
(\s+color=\"((\#[0-9a-f]{6})|(\#[0-9a-f]{3})|red|green|blue|black|white)\")?
(\s+face=\"(Arial|Courier\sNew|Garamond|Georgia|Tahoma|Verdana)\")?

El # Zeichen sind das, was die Ausnahme mit der etwas irreführenden Meldung "missing )" verursacht hat.

0 Stimmen

Die Reihenfolge der Attribute ist bei mir immer gleich, weil ich den Texteditor verwende. Wegen des @-Zeichens brauche ich mein " nicht zu escapen. Das ist ein guter Hinweis auf "courier new". Das habe ich nicht gesehen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X