2

我有一组要从字符串中删除的字符:"/\[]:|<>+=;,?*'@

我正在尝试:

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

private string Clean(string stringToClean)
{
    return Regex.Replace(stringToClean, "[" + Regex.Escape(CHARS_TO_REPLACE) + "]", "");
}

但是,结果与类似的输入严格相同"Foo, bar and other"

我的代码有什么问题?

这个问题看起来很多,但是使用黑名单而不是白名单,所以我删除了 not in ^char。

4

7 回答 7

5

你没有逃脱右方括号CHARS_TO_REPLACE

于 2012-06-15T15:14:07.917 回答
3

如前所述(但答案突然消失了),Regex.Escape不会 escape ],所以你需要调整你的代码:

    return Regex.Replace(stringToClean, "[" + Regex.Escape(CHARS_TO_REPLACE)
          .Replace("]", @"\]") + "]", " ");
于 2012-06-15T15:21:38.070 回答
3

问题是对Regex.Escape工作原理的误解。来自 MSDN:

通过用转义码替换最小字符集(\、*、+、?、|、{、[、(,)、^、$、.、# 和空格)来转义它们。

它按预期工作,但您需要将元字符视为字符类之外Regex.Escape的转义元字符。当你使用一个字符类时,你想要在里面转义的东西是不同的。例如,在字符类内部应该转义为文字,否则它可以充当字符范围(例如,)。-[A-Z]

在你的情况下,正如其他人所提到的,]没有逃脱。对于任何在字符类中具有特殊含义的字符,您需要在调用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);

否则,你会得到["/\\\[]:\|<>\+=;,\?\*'@],它没有]转义,所以它实际上["/\\\[]是一个字符类,然后:\|<>\+=;,\?\*'@]是模式的其余部分,除非你的字符串完全匹配那些剩余的字符,否则它不会匹配。

于 2012-06-15T15:27:03.353 回答
1

有许多字符CHARS_TO_REPLACE对于正则表达式来说是特殊的,需要用斜杠进行转义\

这应该有效:

"/\[]:\|<>\+=;,\?\*'@
于 2012-06-15T15:15:11.480 回答
1

为什么不这样做:

 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;
    }
于 2012-06-15T15:15:31.730 回答
1

单语句 linq 解决方案:

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

private string Clean(string stringToClean) {
    return CHARS_TO_REPLACE
        .Aggregate(stringToClean, (str, l) => str.Replace(""+l, ""));
}
于 2012-06-15T15:32:18.680 回答
0

为了知识起见,这里有一个适用于非常大的字符串(甚至是流)的变体。这里没有正则表达式,只需使用 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());
        }
    }
}
于 2012-06-15T15:52:15.387 回答