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"

私のコードの何が問題になっていますか?

これはこの質問には多くのように見えますが、文字のホワイトリストではなくブラックリストを使用しているため、文字ではないものを削除しました^

4

7 に答える 7

5

で閉じ角かっこをエスケープしませんでしたCHARS_TO_REPLACE

于 2012-06-15T15:14:07.917 に答える
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 に答える
3

すでに述べたように(しかし答えは突然消えました)、Regex.Escapeエスケープしない]ので、コードを微調整する必要があります:

    return Regex.Replace(stringToClean, "[" + Regex.Escape(CHARS_TO_REPLACE)
          .Replace("]", @"\]") + "]", " ");
于 2012-06-15T15:21:38.070 に答える
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 に答える
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 に答える
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 に答える