为什么在这个正则表达式中左括号被转义?

时间:2008-10-27 14:35:55

标签: c# .net regex

我正在使用此处找到的HTML清理白名单代码:
http://refactormycode.com/codes/333-sanitize-html

我需要添加“font”标记作为匹配的附加标记,因此我尝试在<img标记检查后添加此条件

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的在线正则表达式测试程序运行表达式,但它们似乎都没有告诉我任何问题。

我在正则表达式中遗漏了导致括号逃脱的内容吗?我需要做些什么来解决这个问题?

更新
经过大量的反复试验,我记得#符号是正则表达式中的注释。解决这个问题的关键是逃避#字符。如果其他人遇到同样的问题,我已经包含了我的修复程序(只是转发#标志)

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 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:2)

我没有看到正则表达式有任何明显错误。我会尝试通过删除正则表达式的部分来解决问题直到问题消失,然后专注于导致问题的部分。

答案 2 :(得分:1)

它对我来说很好......你使用的是什么版本的.NET框架,以及完全例外是什么?

另外 - 你IsMatch方法是什么样的?这只是Regex.IsMatch的传递吗?

[更新]问题是OP的示例代码没有显示他们正在使用IgnorePatternWhitespace正则表达式选项;使用此选项它不起作用;没有这个选项(即如所示),代码就可以了。

答案 3 :(得分:1)

下载Chris Sells Regex Designer。它是测试.NET正则表达式的一个很好的免费工具。

我不确定这个正则表达式会做你想要的,因为它取决于你在正则表达式中匹配的属性的顺序。例如,如果face =“Arial”在size =“5”之前,则face =将不匹配。

你的正则表达式有一些逃避问题。你需要逃避你的“使用\你需要使用\来逃避你的#你需要在Courier New中使用\ s而不仅仅是空格。你需要使用RegexOptions.IgnorePatternWhitespace和RegexOptions.IgnoreCase选项。

#字符是导致异常的原因,但有些误导性消息)。