Название: Распарсить строку INI-файла Отправлено: titan83 от Январь 18, 2016, 17:29 Коллеги. Полдня парюсь - не могу сделать Regexp для того, чтобы парснуть такую строку:
Name = Value ; some comment В результате хочу иметь QVariantList, где имя -> Name, а значение -> Value. Коммент должен игнорироваться. Сейчас использую такую строку: ^\s*([^(\s*\=\s*)]+)\s*\=\s*([\d\D]*) Строку без комментария в конце она парсит правильно, а вот дальше добавить отсечение того, что после ';' - не получается. Буду очень признателен, если кто-то подскажет. Спасибо. Название: Re: Распарсить строку INI-файла Отправлено: gil9red от Январь 18, 2016, 17:43 ^(\w+) *= *(\w+) *; *.*$
Ссылка на тестер: https://regex101.com/r/rU0jK4/1 Название: Re: Распарсить строку INI-файла Отправлено: Igors от Январь 19, 2016, 10:25 Ах как активно, рьяно это заучивается :)
Название: Re: Распарсить строку INI-файла Отправлено: kambala от Январь 19, 2016, 14:26 в данном случае без регулярок будет сделать проще, понятнее и быстрее
Название: Re: Распарсить строку INI-файла Отправлено: Igors от Январь 19, 2016, 14:41 в данном случае без регулярок будет сделать проще, понятнее и быстрее Хотел сказать то же самое - но уже боюсь трогать "священную корову" (затравили :))Название: [Решено] Re: Распарсить строку INI-файла Отправлено: titan83 от Январь 26, 2016, 13:20 gil9red, спасибо за ответ.
Переключался на другую задачу, поэтому тут затормозил. мой результат такой: ^\s*(;?)\s*(\S+)\s*=\s*\"?([^;"]+[()\w+\s*]+)\"?\s*;? Этот рекэкс парсит и комментарий с начала строки ("; Test1 = Value1"), игнорирует комментарии в той же строке после имени-значения ("Test1 = Value1 ; comment") при этот комментарий может как присутствовать, так и отсутствовать. Также значение можно писать, как в кавычках ("Value1"), так и без кавычек (Value1). Комментарий в конце строки игнорируется. Т.е. в итоге получаю три группы: 1. Символ ';' или '', если символ есть, значит вся строка комментарий. 2. Название параметра. 3. Значение параметра. На мой взгляд получилось более чем достойно. в данном случае без регулярок будет сделать проще, понятнее и быстрее Не согласен: регулярки - суть готовый автомат состояний, да они сложны для понимания, особенно по началу, но результат того стоит.Всем еще раз спасибо за участие. Название: Re: [Решено] Re: Распарсить строку INI-файла Отправлено: Igors от Январь 26, 2016, 14:21 Также значение можно писать, как в кавычках ("Value1"), так и без кавычек (Value1). На этом я неск раз залетал - возможны "кривые" кавычки, смотрятся почти также но символ другоймой результат такой: Ой :)^\s*(;?)\s*(\S+)\s*=\s*\"?([^;"]+[()\w+\s*]+)\"?\s*;? ... На мой взгляд получилось более чем достойно. Название: Re: Распарсить строку INI-файла Отправлено: gil9red от Январь 26, 2016, 14:24 А не проще использовать не свой формат, а стандартный? Тот же xml или json
Название: Re: Распарсить строку INI-файла Отправлено: kambala от Январь 26, 2016, 15:49 в данном случае без регулярок будет сделать проще, понятнее и быстрее Не согласен: регулярки - суть готовый автомат состояний, да они сложны для понимания, особенно по началу, но результат того стоит.вот скажи: сколько ты потратил времени на то, чтобы составить свою регулярку? а сколько бы ты потратил времени на следующий код, делающий то же самое? Код
Название: Re: Распарсить строку INI-файла Отправлено: Igors от Январь 26, 2016, 16:49 вот скажи: сколько ты потратил времени на то, чтобы составить свою регулярку? а сколько бы ты потратил времени на следующий код, делающий то же самое? Ну тут можно предъявить немало претензийКод
1) строка может быть и пустой (летим на первой строчке) 2) а если nameValue.isEmpty() вернет true (не ошибка, но нужен еще код) 3) никто не обещал что будут пробелы до и после "=" 4) знака равенства может вообще не быть (летим на последней строке) 5) возможны доп пробелы, напр " = " (нужен еще trimmed) 6) все-таки копирование интенсивное (хотя в UI это терпимо) Думается такие "противные мелочи" (постоянно вылазят, доделывать) и побуждают молодых людей юзать "регулярки". А дальше срабатывает инерция: "я же не даром учил!" ...изучить новую технологию... Совершенно верно, "технология" - и НИКАКОГО отношения к программированию она не имеет. Может знание этой технологии и добавит программисту "очков" (напр при приеме на работу) - но может и нет.А ведь аккуратный разбор (без всяких регулярок) - отличная тренировка логического мЫшления. Напр что если в стиле wxWidgets (в одном проекте с ним работал и тамошний строчник сподобався) Код Вроде ни одного malloc :) Да, придется написать пару однострочных inline, но они всегда нужны. Название: Re: Распарсить строку INI-файла Отправлено: kambala от Январь 26, 2016, 17:03 0) суть же была не в том, чтобы в мельчайших подробностях написать код :)
1) как мы полетим, если после сплита получится список из одного элемента — пустой строки? 2) само собой, но я не знаю как автор такое обрабатывает 3) автор нам обещает. Тут (как и в случае с ; ) можно разбить по \s*=\s* 4) опять же автор нам обещает. но тут мы и правда полетим при доступе к элементу с индексом 1 5) см. 0 Название: Re: Распарсить строку INI-файла Отправлено: Igors от Январь 26, 2016, 17:12 3) автор нам обещает. .. Не надо быть таким доверчивым :) А вообще Ваш новый ход мысли мне нравится (раньше тоже были регулярки на любой чих)4) опять же автор нам обещает .. Название: Re: Распарсить строку INI-файла Отправлено: Old от Январь 26, 2016, 17:13 А ведь аккуратный разбор (без всяких регулярок) Ну я бы не назвал это аккуратным разбором.... Вроде ни одного malloc :) malloc там может быть и нет, но строка разбирается в 3 (три) прохода, хотя легко разбирается и в один. Название: Re: Распарсить строку INI-файла Отправлено: kambala от Январь 26, 2016, 17:46 А вообще Ваш новый ход мысли мне нравится (раньше тоже были регулярки на любой чих) если регулярное выражение несложное для написания и понимания, лучше использовать его. здесь как раз не такой случай.Название: Re: Распарсить строку INI-файла Отправлено: kai666_73 от Январь 26, 2016, 18:43 Подолью масла в огонь:
Код: boost::property_tree::ini_parser::read_ini Название: Re: Распарсить строку INI-файла Отправлено: titan83 от Январь 27, 2016, 16:24 )))
Не ожидал - тут даже мини холиварчик наметился)) Хотя доля правды в словах про технологию и очки есть, мне кажется ;) На самом деле все затеивается для возможности ЗАПИСАТЬ ini из программы, не меняя его структуру. Т.е. для read-only ini меня полностью устраивает функционал QSettings, но если меняешь какое-нибудь значение из программы, то QSettings уберет все комментарии, перетасует все поля и будет в своем праве ;) А у меня ini еще и людьми читаются, поэтому, кстати, я и не использую xml - формат супер, но для целевой аудитории будет сложноват. Я в xml храню всю информацию о ini-файле - какие поля должны присутствовать, какие в них допустимы значения, как отображать названия полей в GUI - это удобно. Название: Re: Распарсить строку INI-файла Отправлено: titan83 от Январь 27, 2016, 16:28 На счет QString.split() - в начале своего пути я именно им и пользовался, вроде, все работает, но шаг в сторону - расстрел, тьфу - segfault, а если не хочешь segfault'ов, то изволь обложить все if-then, и вот тут понимаешь, что уже все не так и просто и элегантно.
Что бы тут не говорили старшие товарищи, но я пока что считаю regexp вполне удобным инструментом для работы с текстом, лишенным многих недостатков split(). Название: Re: Распарсить строку INI-файла Отправлено: Racheengel от Январь 27, 2016, 16:30 а если строка будет типа
Key = "String1; String2;" ; blabla то надо учитывать и комменты межды кавычками... Название: Re: Распарсить строку INI-файла Отправлено: titan83 от Январь 27, 2016, 18:30 а если строка будет типа Key = "String1; String2;" ; blabla то надо учитывать и комменты межды кавычками... epic fail - вы правы))) На самом деле выяснилось, что заказчик планирует все же хранить настройки в БД, так что на это дело я пока забиваю. Название: Re: Распарсить строку INI-файла Отправлено: Igors от Январь 28, 2016, 08:37 На счет QString.split() - в начале своего пути я именно им и пользовался, вроде, все работает, но шаг в сторону - расстрел, тьфу - segfault, а если не хочешь segfault'ов, то изволь обложить все if-then, и вот тут понимаешь, что уже все не так и просто и элегантно. Возможно QString::split - худшее что есть в Qt. С точки зрения производительности это ужасно, но главное -такие ф-ции развращают пользующегося. Немного подумать и сделать (ведь задачка-то в общем для начинающих) ему уже в лом, хочется вот так ляпнуть контейнером - и все готово.Что бы тут не говорили старшие товарищи, но я пока что считаю regexp вполне удобным инструментом для работы с текстом, лишенным многих недостатков split(). Человек недавно потративший время/силы на регулярки иначе считать не может - это нормально, должно пройти время (может значительное) для "переоценки ценностей". Поэтому "пока что" (ростки демократии) - уже хорошо :) [off]Респект модератору, правильно убрал грубияна с яичками [/off] |