Почему в этом регулярном выражении исключается левая скобка? - PullRequest
4 голосов
/ 27 октября 2008

Я использую код белого списка для очистки HTML, найденный здесь:
http://refactormycode.com/codes/333-sanitize-html

Мне нужно было добавить тег «font» в качестве дополнительного тега для соответствия, поэтому я попытался добавить это условие после проверки <img tag

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);
    }
}

Помимо вышеуказанного условия, мой код практически идентичен коду на странице, на которую я ссылался. Когда я пытаюсь проверить это в C #, выдается исключение, говорящее «Not enough )'s». Я посчитал скобки несколько раз и проверил это выражение через несколько онлайн-тестеров регулярных выражений на основе Javascript, и ни один из них, похоже, не говорит мне о каких-либо проблемах.

Я что-то упускаю в своем регулярном выражении, что приводит к удалению скобок? Что мне нужно сделать, чтобы это исправить?

UPDATE
После долгих проб и ошибок я вспомнил, что знак # - это комментарий в регулярных выражениях. Ключом к исправлению этой ошибки является экранирование символа #. На случай, если кто-то еще столкнется с той же проблемой, я включил свое исправление (просто экранирование знака #)

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);
    }
}

Ответы [ 4 ]

5 голосов
/ 27 октября 2008

Ваш метод IsMatch использует опцию RegexOptions.IgnorePatternWhitespace, которая позволяет вам помещать комментарии внутри регулярных выражений, поэтому вам нужно ограничить # chatacter, в противном случае он будет интерпретироваться как комментарий.

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);
}
2 голосов
/ 27 октября 2008

Я не вижу ничего явно неправильного в регулярном выражении. Я хотел бы попытаться изолировать проблему, удалив части регулярного выражения, пока проблема не исчезнет, ​​а затем сосредоточиться на части, которая вызывает проблему.

1 голос
/ 27 октября 2008

Скачать Chris Sells Regex Designer . Это отличный бесплатный инструмент для тестирования .NET регулярных выражений.

Я не уверен, что это регулярное выражение будет делать то, что вы хотите, потому что это зависит от порядка атрибутов, совпадающих с тем, что у вас есть в регулярном выражении. Если, например, face = "Arial" предшествует size = "5", тогда face = не будет соответствовать.

В вашем регулярном выражении есть некоторые проблемы с побегом. Вам нужно экранировать "с \". Вам нужно экранировать # с \. Вам нужно использовать \ s в Courier New вместо просто пробела. Вам нужно использовать параметры RegexOptions.IgnorePatternWhitespace и RegexOptions.IgnoreCase.

Символы # - это то, что вызывало исключение с несколько вводящим в заблуждение пропущенным сообщением.

1 голос
/ 27 октября 2008

Это прекрасно работает для меня ... какую версию .NET Framework вы используете, и что является точным исключением?

Кроме того - как выглядит IsMatch метод? это просто пропуск Regex.IsMatch?

[обновление] Проблема в том, что пример кода OP не показал, что он использует параметр регулярного выражения IgnorePatternWhitespace; с этой опцией это не работает; без этой опции (т. е. как представлено) код в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...