Есть текст вида:
"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 = @"(?<!^)(?=\d+\))";
var result = Regex.Split(text, splitPattern);
var selectPattern = @"(\d+)\s*\)\s*(.+)";
var questions = result.Select(r => Regex.Match(r, selectPattern).Groups)
.ToDictionary(g => g[1].Value, g => g[2].Value);
Здесь:
В выражении для разбиения:
(?<!...) — Негативный просмотр назад, т.е. находим (не)совпадение перед тем местом, по которому нужно разрезать строку, но само совпадение не включаем в результат
^ — Начало строки
(?=...) — Позитивный просмотр вперед, т.е. находим совпадение после того места, по которому нужно разрезать строку, но само совпадение не включаем в результат
\d+ — Одна или более цифр
\) — Закрывающая скобка
В выражении для выбора номера и тела вопроса:
(\d+) — Одна или более цифр, помещаем в первую группу (потом будем использовать в качестве ключа словаря: g[1]
\s* — Любое количество пробельных символов (вне групп, т.к. они нам не нужны)
\) — Закрывающая скобка (вне групп)
\s* — Любое количество пробельных символов (вне групп)
(.+) — Все символы до конца строки, помещаем во вторую группу
Результат:
Либо в один этап:
var text = "1) первый вопрос 2) второй вопрос 3)вопрос и тд";
var pattern = @"(\d+)\s*\)\s*(.+?)(?=\s*(\d+\)|$))";
var questions = Regex.Matches(text, pattern)
.OfType<Match>()
.ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value);
Здесь:
(\d+) — Одна или более цифр, помещаем в первую группу
\s* — Любое количество пробельных символов, вне групп
\) — Закрывающая скобка, вне групп
\s* — Любое количество пробельных символов, вне групп
(.+?) — Любые символы, здесь ленивый выбор, иначе будет захвачена вся строка за один раз
(?=...) — Позитивный просмотр вперед
\s* — Любое количество пробельных символов
(...|...) — Или то или то
\d+\) — Одна или более цифр + зарывающая скобка
$ — Конец строки
Результат:
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Изучаю asterisk и на данный момент уже поднял сервер на Ubuntu и совершаю звонки с/на устройствахИнтересует вопрос: можно ли каким-нибудь образом...
очень прошу помочь мне оптимизировать скрипт (xml парсер) по памяти
В базе есть строка такого вида a:3:{i:0;s:16:"Женщинам";i:1;s:12:"одежда";i:2;s:14:"Пиджаки";} те функция php serialize нужно осуществить поиск по словам: Женщинам...
Вот простое требованиеЗаходишь на сайт как гость и видишь сообщение типа "авторизуйтесь для просмотра записей", войдя на сайта видны все...