Страницы

Поиск по вопросам

понедельник, 8 апреля 2019 г.

Как разбить строку с текстом в список?

Есть текст вида:
"1) первый вопрос 2) второй вопрос 3)вопрос и тд"
Как наименее трудозатратно (наименьшим кодом) его можно распарсить в массив строк по номерам. Понятно что можно посимвольно считывать, запоминать позицию, вырезать подстроку, но может есть более простое решение, м.б. регулярки?


Ответ

Можно и регуляркой:
var text = "1) первый вопрос 2) второй вопрос 3)вопрос и тд"; var pattern = @"\s*\d+\)\s*"; var result = Regex.Split(text, pattern) .Where(s => !string.IsNullOrWhiteSpace(s)) // Выбросим пустые куски (первый точно будет пустым) .ToList();
Здесь:
\s* — Любое количество пробельных символов \d+ — Одна или более цифр \) — Закрывающая скобка \s* — Любое количество пробельных символов
Результат:


Если вы хотите запомнить также и номер вопроса, то можно сделать это в 2 этапа: сначала разбиваем строку на куски по \d+\) не включая само совпадение, а потом из каждого куска выбрать отдельно номер и тело вопроса:
var text = "1) первый вопрос 2) второй вопрос 3)вопрос и тд"; var splitPattern = @"(? Regex.Match(r, selectPattern).Groups) .ToDictionary(g => g[1].Value, g => g[2].Value);
Здесь:
В выражении для разбиения: (?В выражении для выбора номера и тела вопроса: (\d+) — Одна или более цифр, помещаем в первую группу (потом будем использовать в качестве ключа словаря: g[1] \s* — Любое количество пробельных символов (вне групп, т.к. они нам не нужны) \) — Закрывающая скобка (вне групп) \s* — Любое количество пробельных символов (вне групп) (.+) — Все символы до конца строки, помещаем во вторую группу
Результат:

Либо в один этап:
var text = "1) первый вопрос 2) второй вопрос 3)вопрос и тд"; var pattern = @"(\d+)\s*\)\s*(.+?)(?=\s*(\d+\)|$))"; var questions = Regex.Matches(text, pattern) .OfType() .ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value);
Здесь:
(\d+) — Одна или более цифр, помещаем в первую группу \s* — Любое количество пробельных символов, вне групп \) — Закрывающая скобка, вне групп \s* — Любое количество пробельных символов, вне групп (.+?) — Любые символы, здесь ленивый выбор, иначе будет захвачена вся строка за один раз (?=...) — Позитивный просмотр вперед \s* — Любое количество пробельных символов (...|...) — Или то или то \d+\) — Одна или более цифр + зарывающая скобка $ — Конец строки
Результат:

Комментариев нет:

Отправить комментарий