Поменять местами соседние слова

133
14 апреля 2021, 07:50
string text = "Один два три четыре пять шесть семь восемь девять десять одиннадцать";
Regex regex = new Regex(@"(\w+)(.*?)(\w+)");
Console.WriteLine(regex.Replace(text, "$3$2$1"));

С таким кодом возникает проблема с последним словом:

два Один четыре три шесть пять восемь семь десять девять ьодиннадцат

Answer 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);

См. демо онлайн.

READ ALSO
Downcast ComboBox в Win Forms

Downcast ComboBox в Win Forms

У меня есть класс FurnitureComboBox, который является наследником ComboBoxПытаюсь привести ComboBox к FurnitureComboBox (от базового к производному) и чего-то не понимаю

67
ReCaptcha в Selenium WebDriver C#

ReCaptcha в Selenium WebDriver C#

Пытаюсь авторизоваться на сайте, но при решении ReCaptcha руками(ставиться пауза в скрипте), выводится ошибка "Повторите попытку"

83
Почему не работает программа ? Данная программа предназначена для вывода значений уровня владения иностранным языком на консоль с помощью Enum [закрыт]

Почему не работает программа ? Данная программа предназначена для вывода значений уровня владения иностранным языком на консоль с помощью Enum [закрыт]

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском

100
Остановка времени в программе извне (получаемого из timeGetTime)

Остановка времени в программе извне (получаемого из timeGetTime)

Есть ли способ подцепить функцию получения времени через timeGetTime в сторонней программе?

100