自定义正则表达式以排除字符列表

时间:2019-04-05 16:49:11

标签: c# regex

我有一个程序,其中有很多字符串常量,用于通过正则表达式允许特定字符。现在,我有了要在任何地方阻止的字符列表,但我不想再遍历所有旧的字符串常量并重写它们。相反,我想创建受限字符列表并仅在一个位置(以防将来更改)编辑该列表。然后,我将通过自定义的正则表达式运行所有字符串常量。

我有在web.config中定义的受限字符列表,如下所示:

<add key="RestrChar" value="\,!,#,%,&lt;,&gt;,|,&amp;,;"/>

像这样调用自定义正则表达式:

[RestrictCharRegExpress(ConstantStringName, ErrorMessage = CustomErrMsg)]
public string StringName

类定义如下:

public class RestrictCharRegExpressAttribute : RegularExpressionAttribute
{
   public RestrictCharRegExpressAttribute(string propRegex) : base(GetRegex(propRegex)){ }

   private static string GetRegex(string propRegex)
   {
        string restrictedChars = ConfigureationManager.AppSettings.Get("RestrChar");
        string[] thisCharArray = restrictedChars.Split(',');
        string regexPrep = "";
        foreach (string c in thisCharArray)
        {
            regexPrep = string.Format(@"""{0}""", c);
            propRegex = Regex.Replace(propRegex, regexPrep, "");
        }
        return propRegex;
    }
}

但是它并没有像我期望的那样删除字符。我究竟做错了什么?

先谢谢您。

2 个答案:

答案 0 :(得分:1)

您可以添加正向超前子表达式来强制匹配符合以下模式

(?=^[^yourcharlisthere]*$)

将您的字符串锚定在开头和结尾,因为匹配的字符串中必须没有所有字符。

或者您可以添加否定的超前子表达式,只要该字符串在列表中具有一个字符就拒绝。

(?![yourcharlisthere])

这一次您不需要锚定,只要其中一个字符匹配,就完全匹配子表达式,因此,您的字符串将被拒绝。只需在原始正则表达式的开头添加这些字符即可。

答案 1 :(得分:1)

您可以删除foreach并使用

private static string GetRegex(string propRegex)
{
    string restrictedChars = ConfigureationManager.AppSettings.Get("RestrChar");
    string[] thisCharArray = restrictedChars.Split(',');
    return Regex.Replace(propRegex, 
        $"[{string.Concat(thisCharArray)}]+", "");
}

请注意,如果使用此方法,则只需要转义^-\]

如果您将它们保留在value中,则可以在代码中完成:

var regex = string.Concat(
        thisCharArray.Select(x => 
            x.Replace("\\", @"\\").Replace("]", @"\]").Replace("^", @"\^").Replace("-", @"\-")
        )
 );
 return Regex.Replace(propRegex, 
        $"[{regex}]+", "");