string text = "Один два три четыре пять шесть семь восемь девять десять одиннадцать";
Regex regex = new Regex(@"(\w+)(.*?)(\w+)");
Console.WriteLine(regex.Replace(text, "$3$2$1"));
С таким кодом возникает проблема с последним словом:
два Один четыре три шесть пять восемь семь десять девять ьодиннадцат
Старайтесь писать такие регулярные выражения, в которых каждый следующий шаблон не находит совпадения, которое находит предыдущий. Таким образом, можно избежать множества проблем, как текущей, так и других (например, "catastrophic backtracking").
Посмотрите, к чему сводится оригинальное выражение в случае, если на входе строка из цифробуквенных символов и символов подчёркивания:
(\w+)(.*?)(\w+) => (\w+)(\w+) => (\w+)(\w)
Слово одиннадцать разбивается на одиннадцат и ь, так как первый \w+ "забирает" все символы в слове, а затем "отдаёт" последний второй группе, (\w) (так как он должен "найти" хотя бы 1 символ.
Шаблон (.*?) находит любой символ, отличный от символа перехода на новую строку. Т.е. он находит те же символы, что и \w. Это не имеет смысла в данной ситуации: тут нужно найти два слова как минимум. Значит, между первым и вторым \w+ должен быть шаблон, обратный \w+. Т.е. это либо \W+ (1 и более символов, отличных от букв, цифр, символа подчеркивания и некоторых диакритических знаков, т.к. используется в .NET).
Используйте
var text = "Один два три четыре пять шесть семь восемь девять десять одиннадцать";
Console.WriteLine(Regex.Replace(text, @"(\w+)(\W+)(\w+)", "$3$2$1"));
Демо регулярного выражения
Бонус: поменять порядок слов можно с помощью
var line = "Один два три четыре пять шесть семь восемь девять десять одиннадцать";
var result = string.Concat(Regex.Split(line, @"(\W+)").Reverse());
Console.WriteLine(result);
См. демо онлайн.
Продвижение своими сайтами как стратегия роста и независимости