Похоже, вам нужна динамическая декартова функция для этого. Сообщение Эрика Липперта , написанное в ответ на Генерация всех возможных комбинаций .
Во-первых, нам нужно проанализировать входную строку:
Regex ex = new Regex(@"(?<=\{)(?<words>\w+(\|\w+)*)(?=\})");
var sentence = "The {small|big} car is {red|blue}";
тогда входная строка должна быть изменена для использования в string.Format
-подобных функциях:
int matchCount = 0;
var pattern = ex.Replace(sentence, me =>
{
return (matchCount++).ToString();
});
// pattern now contains "The {0} car is {1}"
тогда нам нужно найти все совпадения и применить превосходный метод расширения CartesianProduct
Эрика:
var set = ex.Matches(sentence)
.Cast<Match>()
.Select(m =>
m.Groups["words"].Value
.Split('|')
).CartesianProduct();
foreach (var item in set)
{
Console.WriteLine(pattern, item.ToArray());
}
это даст:
The small car is red
The small car is blue
The big car is red
The big car is blue
и, наконец, метод CartesianProduct
(взят из здесь ):
static IEnumerable<IEnumerable<T>> CartesianProduct<T>(
this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] {item}));
}