Я пишу приложение в.NET, которая генерирует случайный текст на основе некоторого входа. Таким образом, если у меня есть текст как "I love your {lovely|nice|great} dress"
Я хочу выбрать случайным образом из lovely/nice/great
и используйте это в тексте. Любые предложения в C# или VB.NET приветствуются.
Вы можете сделать это, используя регулярное выражение для замены каждого {...}
. Функция Regex.Replace
может принимать MatchEvaluator
, который может выполнять логику для выбора случайного значения из вариантов:
Random random = new Random();
string s = "I love your {lovely|nice|great} dress";
s = Regex.Replace(s, @"\{(.*?)\}", match => {
string[] options = match.Groups[1].Value.Split('|');
int index = random.Next(options.Length);
return options[index];
});
Console.WriteLine(s);
Пример вывода:
I love your lovely dress
Обновление: переведено в VB. NET автоматически с использованием .NET Reflector :
Dim random As New Random
Dim s As String = "I love your {lovely|nice|great} dress"
s = Regex.Replace(s, "\{(.*?)\}", Function (ByVal match As Match)
Dim options As String() = match.Groups.Item(1).Value.Split(New Char() { "|"c })
Dim index As Integer = random.Next(options.Length)
Return options(index)
End Function)
Это может быть немного злоупотреблением функциями настраиваемого форматирования, доступными через интерфейсы ICustomFormatter и IFormatProvider, но вы можете сделать что-то вроде этого:
public class ListSelectionFormatter : IFormatProvider, ICustomFormatter
{
#region IFormatProvider Members
public object GetFormat(Type formatType)
{
if (typeof(ICustomFormatter).IsAssignableFrom(formatType))
return this;
else
return null;
}
#endregion
#region ICustomFormatter Members
public string Format(string format, object arg, IFormatProvider formatProvider)
{
string[] values = format.Split('|');
if (values == null || values.Length == 0)
throw new FormatException("The format is invalid. At least one value must be specified.");
if (arg is int)
return values[(int)arg];
else if (arg is Random)
return values[(arg as Random).Next(values.Length)];
else if (arg is ISelectionPicker)
return (arg as ISelectionPicker).Pick(values);
else
throw new FormatException("The argument is invalid.");
}
#endregion
}
public interface ISelectionPicker
{
string Pick(string[] values);
}
public class RandomSelectionPicker : ISelectionPicker
{
Random rng = new Random();
public string Pick(string[] values)
{
// use whatever logic is desired here to choose the correct value
return values[rng.Next(values.Length)];
}
}
class Stuff
{
public static void DoStuff()
{
RandomSelectionPicker picker = new RandomSelectionPicker();
string result = string.Format(new ListSelectionFormatter(), "I am feeling {0:funky|great|lousy}. I should eat {1:a banana|cereal|cardboard}.", picker, picker);
}
}
String.Format("static text {0} more text {1}", randomChoice0, randomChoice1);
написать простой парсер, который получит информацию в скобках, разделит ее с помощью string.Split
, получит случайный индекс для этого массива и снова построит строку.
использовать StringBuilder
для построения результата из-за проблем с производительностью других строковых операций.