Замена регулярных выражений С#

Я добавляю фильтр ненормативной лексики, и я хотел бы заменить слово (или часть слова), которое заменено строкой равной длины. Часть равной длины - это то, где у меня возникают трудности.

Поэтому, если заменяемое слово имеет длину 3 символа, я хочу, чтобы текст, на который оно было заменено, имел длину 3 символа. Я не уверен, как я могу подстроить свою строку замены, чтобы она соответствовала длине заменяемого слова.

Вот мой метод тестирования:

public static string ProfanityFilter(this string text)
{
    string pattern = @"\bword\b|\bword2\b|\banother*";
    Regex regex = new Regex(pattern);
    string replacement = "*%$@^!#@!@$^()!";
    return regex.Replace(text, replacement);
}

Таким образом, если слово «другой» заменить, оно будет заменено на «*%$@^!#».

Если "слово" заменить, оно будет заменено на "*%$@^"

Если "формулировка" заменена, она будет заменена на "*%$@^ing"

Обновлять:

В итоге я нашел решение...

Я создал новый метод:

 public static string Censored(Match match)
        {
            string replacement = "*%$@^!#@!@$^()!";
            return replacement.Substring(0, match.Captures[0].Length);
        }

Затем изменил

return regex.Replace(text, replacement);

to

return regex.Replace(text, Censored);

person GregInWI2    schedule 16.03.2011    source источник
comment
Имейте в виду, что ваш новый метод, использующий Substring, вызовет исключение, если длина захвата превышает длину строки замены. Более безопасным способом было бы создать строку замены из набора разных символов, если вы действительно хотите, чтобы она состояла из всех этих разных символов. В противном случае вы можете указать один символ и создать его с помощью конструктора String, как я показал в своем ответе.   -  person Ahmad Mageed    schedule 16.03.2011
comment
Интересно посмотреть, что получится при назначении.   -  person Jim Mischel    schedule 16.03.2011
comment
Я знаю, что он мог превышать его, и там не было проверки :) Я не закончил.   -  person GregInWI2    schedule 18.03.2011


Ответы (1)


Попробуйте этот подход:

string input = "foo word bar word2 foobar another";
string pattern = @"\b(?:word|word2|another)\b";
string result = Regex.Replace(input, pattern, m => new String('*', m.Length));
Console.WriteLine(result);

Идея состоит в том, чтобы использовать перегруженный метод Regex.Replace, который принимает MatchEvaluator делегата. Я предоставляю MatchEvaluator через лямбда-выражение и получаю доступ к свойству Match.Length, чтобы определить длину совпадающей ненормативной лексики.

Я переделал ваш шаблон, чтобы он имел точные совпадения, поместив метасимвол \b в начало и конец альтернативных совпадений. Однако, исходя из вашего примера "wording" = "*%$@^ing", похоже, вы хотите поддерживать частичные совпадения. В этом случае вам следует опустить использование \b.

person Ahmad Mageed    schedule 16.03.2011
comment
Я попробую. Я также нашел способ и обновил свой вопрос найденным методом. Я соглашусь с вашим после того, как попробую. - person GregInWI2; 16.03.2011