Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法删除字符串中的一组字符_C#_Regex - Fatal编程技术网

C# 无法删除字符串中的一组字符

C# 无法删除字符串中的一组字符,c#,regex,C#,Regex,我想从字符串中删除一组字符:“/\[]:|+=;,?*”@ 我正在尝试: private const string CHARS_TO_REPLACE = @"""/\[]:|<>+=;,?*'@"; private string Clean(string stringToClean) { return Regex.Replace(stringToClean, "[" + Regex.Escape(CHARS_TO_REPLACE) + "]", ""); } privat

我想从字符串中删除一组字符:
“/\[]:|+=;,?*”@

我正在尝试:

private const string CHARS_TO_REPLACE = @"""/\[]:|<>+=;,?*'@";

private string Clean(string stringToClean)
{
    return Regex.Replace(stringToClean, "[" + Regex.Escape(CHARS_TO_REPLACE) + "]", "");
}
private const string CHARS_TO_REPLACE=@“/\[]:|+=;,?*”@";
专用字符串清理(字符串清理)
{
返回Regex.Replace(stringToClean,“[”+Regex.Escape(CHARS_TO_Replace)+“]”,”);
}
但是,结果与输入完全相同,类似于
“Foo、bar和other”

我的代码有什么问题


这看起来很复杂,但是使用了一个黑名单而不是白名单,所以我删除了not in
^
字符。

您没有在
chars\u to\u REPLACE
中转义结束方括号,在
chars\u to\u REPLACE
中有许多字符是Regex特有的,需要用斜杠
\

这应该起作用:

"/\[]:\|<>\+=;,\?\*'@
“/\[]:\\\+=;,\?\*”@
为什么不做:

 private static string Clean(string stringToClean)
    {

        string[] disallowedChars = new string[] {//YOUR CHARS HERE};

        for (int i = 0; i < disallowedChars.Length; i++)
        {
            stringToClean= stringToClean.Replace(disallowedChars[i],""); 
        }

        return stringToClean;
    }
私有静态字符串清理(字符串stringToClean)
{
string[]disallowedChars=新字符串[]{///此处的字符数};
for(int i=0;i
如前所述(但答案突然消失),
Regex.Escape
不会逃逸
]
,因此您需要调整代码:

    return Regex.Replace(stringToClean, "[" + Regex.Escape(CHARS_TO_REPLACE)
          .Replace("]", @"\]") + "]", " ");

问题是对工作原理的误解。从MSDN:

通过用转义码替换最小字符集(\、*、+、?、|、{、[、(、)、^、$、#和空格),对其进行转义

它按预期工作,但您需要将
Regex.Escape
视为在字符类外部转义元字符。当您使用字符类时,您希望在内部转义的内容是不同的。例如,在字符类内部
-
应该转义为文字,否则它可以充当字符范围s(例如,
[A-Z]

在您的情况下,如其他人所述,
]
没有转义。对于character类中具有特殊含义的任何字符,您需要在调用
Regex.Escape
后分别处理它们。这应该满足您的需要:

string CHARS_TO_REPLACE = @"""/\[]:|<>+=;,?*'@";
string pattern = "[" + Regex.Escape(CHARS_TO_REPLACE).Replace("]", @"\]") + "]";

string input = "hi\" there\\ [i love regex];@";
string result = Regex.Replace(input, pattern, "");
Console.WriteLine(result);
string CHARS_TO_REPLACE=@“/\[]:|+=;,?*”@;
字符串模式=“[”+Regex.Escape(CHARS\u TO\u REPLACE.REPLACE(“]),@“\]”+“]”;
string input=“hi\”那里\\[i love regex];@”;
字符串结果=Regex.Replace(输入,模式,“”);
控制台写入线(结果);

否则,您将以
[“/\\[]:\\+=;,\?\*'@
结束,它没有
]
转义,因此它实际上是
[“/\\[]
作为字符类,然后是
:\\+=;,\?*@]
作为模式的其余部分,除非字符串与其余字符完全匹配,否则不会匹配。

单语句linq解决方案:

private const string CHARS_TO_REPLACE = @"""/\[]:|<>+=;,?*'@";

private string Clean(string stringToClean) {
    return CHARS_TO_REPLACE
        .Aggregate(stringToClean, (str, l) => str.Replace(""+l, ""));
}
private const string CHARS_TO_REPLACE=@“/\[]:|+=;,?*”;
专用字符串清理(字符串清理){
将字符返回到替换
.骨料(stringToClean,(str,l)=>str.Replace(“+l”);
}

为了了解更多信息,这里有一个适用于非常大的字符串(甚至流)的变体。这里没有正则表达式,只需使用stringbuilder在每个字符上循环以存储结果:

class Program
{
    private const string CHARS_TO_REPLACE = @"""/\[]:|<>+=;,?*'@";

    static void Main(string[] args)
    {
        var wc = new WebClient();
        var veryLargeString = wc.DownloadString("http://msdn.microsoft.com");

        using (var sr = new StringReader(veryLargeString))
        {
            var sb = new StringBuilder();

            int readVal;
            while ((readVal = sr.Read()) != -1)
            {
                var c = (char)readVal;
                if (!CHARS_TO_REPLACE.Contains(c))
                {
                    sb.Append(c);
                }
            }

            Console.WriteLine(sb.ToString());
        }
    }
}
类程序
{
private const string CHARS_TO_REPLACE=@“/\[]:|+=;,?*'@”;
静态void Main(字符串[]参数)
{
var wc=新的WebClient();
var verylargesting=wc.DownloadString(“http://msdn.microsoft.com");
使用(var sr=新StringReader(veryLargeString))
{
var sb=新的StringBuilder();
int readVal;
而((readVal=sr.Read())!=-1)
{
var c=(char)readVal;
如果(!CHARS_TO_REPLACE.Contains(c))
{
sb.附加(c);
}
}
Console.WriteLine(sb.ToString());
}
}
}

你能打印出正在生成的正则表达式吗?它是
[“/\\\[]:\\\+=;,\?\*”@
你没有看到对
regex.Escape的调用吗?
?显然没有。我会删除我的答案。为什么要麻烦
。包含
检查?这会给我一个编译错误-“与
字符串匹配的最佳重载方法。替换(char,char)
有一些无效参数“哎呀,我以为你在迭代一个字符串literal
Regex。显然,Escape
没有捕捉到结束方块。很好。是的,我得出了相同的解决方案…似乎是.Net framework中的一个小错误。是的,同意!应该被视为bug@SteveB:不是bug-
Regex。转义
不是为构建角色而设计的集合!它用于添加字符串文字作为搜索模式的一部分。实际上,这不是错误。如果您阅读,您将发现“如果右括号或大括号前面没有相应的开头字符,则正则表达式引擎会逐字解释。”。因为我在调用escape后添加了一个前导括号,所以我不满足此规则。这也是一个不错的解决方案。另一个更适合于非常大的流的解决方案是使用StringReader和StringBuilder的组合。但是由于我的字符串非常小(他们真的应该使用make Regex.Escape Escape
]
-
。从字符类中转义这些字符是无害的,它们是元字符(取决于上下文)。