2014-01-07 6 views
2
Random rnd = new Random(DateTime.Now.Millisecond); 

string rt = "tst xtstx xtste tst tst!!"; 

if (rnd.Next(3) == 0) 
{ 
    string[] replaceWords = { "something", "nice" }; 
    rt.Replace("tst", replaceWords[rnd.Next(replaceWords.Length - 1)]); 
} 
if (rnd.Next(3) == 0) 
{ 
    string[] replaceWords = { "cool", "crazy" }; 
    rt.Replace("xtste", replaceWords[rnd.Next(replaceWords.Length - 1)]); 
} 

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

string rt = "tst xtstx xtste tst tst!!"; 
//   /\    /\ /\ 

Существует лучший способ сделать это только заменив слова? Я буду использовать ту же идею несколько раз в своем коде.

+0

@crush Заменяйте ("\ BTST \ Ъ")? –

+0

Я немного смущен точно, что вы хотите сделать, я думаю ... вы можете лучше понять свой вопрос? – crush

ответ

3

Вы должны использовать регулярные выражения для этого.

Regex, которые соответствуют всем tst словам, вам нужно использовать \btst\b regex.

Для замены всех случаев используйте один из методов Regex.Replace.

Here is a something similar example

Также не используйте Random(DateTime.Now.Millisecond), по умолчанию конструктор Random имеет лучшее зерно, чем это.

Пример:

static Random rnd = new Random(); 
static string Replace(string input, string word, params string[] words) 
{ 
    return Regex.Replace(input, "\b" + word + "\b", m=>words[rnd.Next(words.Length)]); 
} 

теперь вы можете использовать его как это:

string rt = "tst xtstx xtste tst tst!!"; 

if (rnd.Next(3) == 0) 
{ 
    rt = Replace(rt, "tst", "something", "nice"); 
} 
if (rnd.Next(3) == 0) 
{ 
    rt = Replace(rt, "xtste", "cool", "crazy"); 
} 
+0

Существует чистый способ сделать это? так как я собираюсь воспроизвести одну и ту же идею несколько раз? –

+0

@ Gorfi, отредактированный с примера –

+0

Мне понадобится несколько, если с Radom rnd это 2 строки? –

1

Сделайте это. Используйте Regex.Replace и /b, чтобы использовать только слово.

Random rnd = new Random(DateTime.Now.Millisecond); 

string rt = "tst xtstx xtste tst tst!!"; 

if (rnd.Next(3) == 0) 
{ 
    string[] replaceWords = { "something", "nice" }; 
    rt = Regex.Replace(rt, @"\tst\b", replaceWords[rnd.Next(replaceWords.Length - 1)]); 
} 
if (rnd.Next(3) == 0) 
{ 
    string[] replaceWords = { "cool", "crazy" }; 
    rt = Regex.Replace(rt, @"\xtste\b", replaceWords[rnd.Next(replaceWords.Length - 1)]); 
} 

способ для выполнения некоторых повторных работ.

public string ReplaceRandom(string[] words, string wordToReplace, string inputString) 
{ 
    Random rnd = new Random(DateTime.Now.Millisecond); 
    inputString = Regex.Replace(inputString, @"\b" + wordToReplace + @"\b", words[rnd.Next(words.Length - 1)]); 
    return inputString; 
} 

Или, если вы хотите использовать метод расширения для рода придерживаться String.Replace линии мышления вы могли бы сделать. Назовите это с rt.ReplaceWithRandom(replaceWords, "tst");

public static string ReplaceWithRandom(this string inputString, string[] words, string wordToReplace) 
{ 
    Random rnd = new Random(DateTime.Now.Millisecond); 
    inputString = Regex.Replace(inputString, @"\b" + wordToReplace + @"\b", words[rnd.Next(words.Length - 1)]); 
} 
+0

Поскольку я использую этот код несколько раз, есть способ сделать его более чистым? –

+0

@ Gorfi вы хотите вывести эту функциональность в отдельную функцию или просто сделать код короче? –

+0

Просто упростите реализацию нового wordToReplace с помощью массива replaceWords. –

1

вы можете использовать \b для обозначения слова boundry с регулярным выражением.

Также - не забудьте назначить обратно исходную строку!

Random rnd = new Random(); 

string rt = "tst xtstx xtste tst tst!!"; 

if (rnd.Next(3) == 0) 
{ 
    string[] replaceWords = { "something", "nice" }; 
    rt = Regex.Replace(rt, @"\btst\b", replaceWords[rnd.Next(replaceWords.Length - 1)]); 
} 
if (rnd.Next(3) == 0) 
{ 
    string[] replaceWords = { "cool", "crazy" }; 
    rt = Regex.Replace(rt, @"\bxtste\b", replaceWords[rnd.Next(replaceWords.Length - 1)]); 
} 
0

Мне кажется, что вы хотите другое случайное слово для каждого матча. Вот класс, который сделает это за вас.

public class RandomStringReplacer 
{ 
    // no need to seed this w/ the current time, the default constructor does that already 
    private readonly Random _random = new Random(); 

    private readonly Regex _regex; 

    private readonly string[] _replacementStrings; 

    public RandomStringReplacer(string pattern, params string[] replacementStrings) 
    { 
     _regex = new Regex(pattern); 
     _replacementStrings = replacementStrings.ToArray(); 
    } 

    // each time we get a replacement string, a randomly selected one is chosen 
    private string RandomReplacement 
    { 
     get { return _replacementStrings[_random.Next(_replacementStrings.Length)]; } 
    } 

    public string Replace(string text) 
    { 
     var random = new Random(); 
     var result = text; 

     // get the matches as a stack, because we want to replace backwards so that indexes still match the correct spot in the string 
     var matches = new Stack<Match>(_regex.Matches(text).OfType<Match>()); 
     while (matches.Count > 0) 
     { 
      var match = matches.Pop(); 
      // each match has a 1/3 chance to be replaced 
      if (random.Next(3) == 0) 
      { 
       result = result.Remove(match.Index, match.Length).Insert(match.Index, RandomReplacement); 
      } 
     } 
     return result; 
    } 
} 

Использование:

var replacements = new[]{"foo", "bar", "FUBAR"}; 
var pattern = @"(tst)|(xtste)"; 
var replacer = new RandomStringReplacer(pattern, replacements); 

var text = "tst xtstx xtste tst tst!!"; 
replacer.Replace(text).Dump(); 
Смежные вопросы