![]() |
Модераторы: korob2001, ginnie |
![]() ![]() ![]() |
|
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Есть текстовый файл. Из него необходимо вырезать комментарии.
1) комментарии отделены от текста двумя линиями из дефисов; текст текст текст --------------------------- здесь комментарий --------------------------- текст текст текст 2) комментарий не может начинаться с цифры 3) длина комментария не может быть более одной строки (любой длины) 4) могут идти два комментария подряд: текст текст текст --------------------------- здесь комментарий --------------------------- здесь комментарий --------------------------- текст текст текст В прикрепленном файле исходник. Это сообщение отредактировал(а) Suppir - 11.2.2011, 15:21 Присоединённый файл ( Кол-во скачиваний: 8 ) ![]() |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Решаемая ли это задача с помощью регулярных выражений?
А вот как должно получиться (файл прикрепил). Это сообщение отредактировал(а) Suppir - 11.2.2011, 15:15 Присоединённый файл ( Кол-во скачиваний: 7 ) ![]() |
|||
|
||||
arto |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1495 Регистрация: 31.10.2004 Репутация: 38 Всего: 40 |
у вас неопределенность -- последний комментарий (который идет с одной линией) может быть только последним
это так и надо? |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
arto,
это не комментарий одной линией. Это двойной комментарий вида текст текст текст --------------------------- здесь комментарий --------------------------- здесь комментарий --------------------------- текст текст текст Вся проблема в этих неопределенностях. Нужно точно определять, где мы находимся, внутри комментария или текста, чтобы случайно не отрезать текст. Добавлено через 5 минут и 55 секунд Еще раз прикрепил оба файла в архиве. Там хорошо видно, как было, и как должно получиться. Присоединённый файл ( Кол-во скачиваний: 3 ) ![]() |
|||
|
||||
arto |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1495 Регистрация: 31.10.2004 Репутация: 38 Всего: 40 |
никак.
если вы поставите двойной комментарий в середине текста, разобраться сможет только автор текста и комментария. выделяйте комментарии правильно. |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
arto,
Думаю, что это можно сделать, благодаря следующей информации: 1) комментарий не может начинаться на цифру 2) комментарий всегда состоит из одной строки. |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
||||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz, здорово!!! Понятное дело, я привел только упрощенный пример (на самом деле все гораздо сложнее). Если у меня еще возникнут вопросы, я в этой же теме напишу. Это сообщение отредактировал(а) Suppir - 11.2.2011, 15:30 |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
||||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz,
на самом деле в 95% случаев длина равна одной строке. Но иногда бывает по несколько строк. Но при этом строки внутри коммента никогда не начинаются на цифру. Можно ли этот случай учесть? |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
Ну тогда оставляйте как есть. В 95% случаев должно работать правильно
![]() Это сообщение отредактировал(а) alezzz - 11.2.2011, 15:40 |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz, из-за этих 5% все алгоритмы сбиваются :
|
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
вот еще вариант, надеюсь перекроет 5%
|
|||
|
||||
arto |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1495 Регистрация: 31.10.2004 Репутация: 38 Всего: 40 |
# perl -0777 -plne 's/^-+\n(?:(?:^[^\d].*\n)+^-+\n)+//mg;'
text A ------------------ comment 1 ------------------ text B ------------------ comment 1.7 ------------------ text C ^D text A text C # |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz,
Вот такой код работает - удаляет случай, когда в комментарии по 2 строки сразу (и только): $text =~ s/^\s*-+\n((^\s*[^\d].*\n){2}^\s*-+\n)+//mg; а такой код слишком много удаляет: $text =~ s/^\s*-+\n(?:(?:^\s*[^\d].*\n)+^\s*-+\n)+//mg; Добавлено через 3 минуты и 35 секунд Я прикрепил к сообщению архив с более сложным случаем (по несколько строк в одном комменте). Добавлено через 6 минут и 46 секунд Кажется, вот такой код заработал: $text =~ s/^ {3}-+\n(?:(?:^ {3}[^\d].*\n)+^ {3}-+\n)+//mg; а вот этот код не работал из-за \s* $text =~ s/^\s*-+\n(?:(?:^\s*[^\d].*\n)+^\s*-+\n)+//mg; Присоединённый файл ( Кол-во скачиваний: 1 ) ![]() |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
||||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
В прикрепленных файлах как раз строка начинается всегда с 3-х пробелов.
Добавлено @ 16:17 Еще один момент. Текст внутри комментария не может начинаться на цифру ИЛИ открывающуюся скобку. Я пишу: $text =~ s/^ {3}-+\n(?:(?:^ {3}[^\d\(].*\n)+^ {3}-+\n)+//mg; по почему-то этот код не срабатывает на скобках. Добавлено @ 16:21 Вот на таком тексте: Статья 117. Нарушение порядка постановки на учет в налоговом органе ------------------------------------------------------------------ Налоговые санкции за нарушение законодательства о налогах и сборах, по которым решение налогового органа было вынесено до дня вступления в силу Федерального закона от 27.07.2010 N 229-ФЗ, взимаются в порядке, действовавшем до дня вступления в силу указанного Федерального закона (пункт 12 статьи 10 Федерального закона от 27.07.2010 N 229-ФЗ). О взыскании налоговых санкций за налоговое правонарушение или иное нарушение законодательства о налогах и сборах, совершенное до дня вступления в силу Федерального закона от 27.07.2010 N 229-ФЗ см. пункт 13 статьи 10 указанного Федерального закона. ------------------------------------------------------------------ Поскольку в силу глав 15, 16 и 18 НК РФ в соответствующих случаях субъектами ответственности являются сами организации, а не их должностные лица, привлечение последних к административной ответственности не исключает привлечения организаций к ответственности, установленной НК РФ (Постановление Пленума ВАС РФ от 27.01.2003 N 2). ------------------------------------------------------------------ Глава 16. ВИДЫ НАЛОГОВЫХ ПРАВОНАРУШЕНИЙ И ОТВЕТСТВЕННОСТЬ ЗА ИХ СОВЕРШЕНИЕ Статья 116. Нарушение порядка постановки на учет в налоговом органе (в ред. Федерального закона от 27.07.2010 N 229-ФЗ) # строка начинается на скобку, значит это НЕ комментарий. ------------------------------------------------------------------ По вопросу, касающемуся административной ответственности должностных лиц за нарушение срока постановки на учет в налоговом органе, см. статью 15.3 Кодекса РФ об административных правонарушениях, который вступил в силу 1 июля 2002 года. ------------------------------------------------------------------ 1. Нарушение налогоплательщиком установленного настоящим Кодексом срока подачи заявления о постановке на учет в налоговом органе по основаниям, предусмотренным настоящим Кодексом, влечет взыскание штрафа в размере 10 тысяч рублей. 2. Ведение деятельности организацией или индивидуальным предпринимателем без постановки на учет в налоговом органе по основаниям, предусмотренным настоящим Кодексом, влечет взыскание штрафа в размере 10 процентов от доходов, полученных в течение указанного времени в результате такой деятельности, но не менее 40 тысяч рублей. Статья 117. Утратила силу. - Федеральный закон от 27.07.2010 N 229-ФЗ. Это сообщение отредактировал(а) Suppir - 11.2.2011, 16:21 |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
||||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz,
да, но дальше ведь есть строка, которая начинается на скобку. Получается что все, начиная от Глава 16. и далее, не является комментарием. |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Можно ли как-то дополнительную проверку организовать с этой скобкой?
Если в захваченном тексте есть строка, которая начинается на скобку или на цифру, то не вырезать этот текст. Это сообщение отредактировал(а) Suppir - 11.2.2011, 18:04 |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
1. Налогоплательщики, принявшие решение о приобретении лицензий на право пользования недрами, в аналитических регистрах налогового учета обособленно отражают расходы, осуществляемые в целях приобретения лицензий. При этом расходы, связанные с приобретением каждой конкретной лицензии, учитываются отдельно.
К расходам, осуществляемым в целях приобретения лицензии, в частности, относятся: расходы, связанные с предварительной оценкой месторождения; расходы, связанные с проведением аудита запасов месторождения; расходы на разработку технико-экономического обоснования (иных аналогичных работ), проекта освоения месторождения; расходы на приобретение геологической и иной информации; расходы на оплату участия в конкурсе (аукционе). (в ред. Федерального закона от 27.07.2010 N 229-ФЗ) ------------------------------------------------------------------ При переходе налогоплательщика на порядок учета расходов на получение (приобретение) лицензии на право пользования недрами в составе прочих расходов расходы на приобретение лицензий, указанные в абзаце восьмом пункта 1 статьи 325, не учтенные в налоговой базе по налогу на прибыль организаций по состоянию на 1 января 2009 года, учитываются равными долями в течение 2009 и 2010 годов (Федеральный закон от 22.07.2008 N 158-ФЗ). ------------------------------------------------------------------ В случае, если налогоплательщик заключает лицензионное соглашение на право пользования недрами (получает лицензию), то расходы, осуществленные налогоплательщиком в целях приобретения лицензии, формируют стоимость лицензионного соглашения (лицензии), которая учитывается налогоплательщиком в составе нематериальных активов, амортизация которых начисляется в порядке, установленном статьями 256 - 259.2 настоящего Кодекса, или по выбору налогоплательщика в составе прочих расходов, связанных с производством и реализацией, в течение двух лет. Избранный налогоплательщиком порядок учета указанных расходов отражается в учетной политике для целей налогообложения. (в ред. Федеральных законов от 22.07.2008 N 158-ФЗ, от 27.07.2010 N 229-ФЗ) # строка начинается со скобки, поэтому этот и вышестоящий абзац не являются комментариями ------------------------------------------------------------------ Положения абзаца девятого пункта 1 статьи 325 (в части сроков признания расходов) (в редакции Федерального закона от 27.07.2010 N 229-ФЗ) применяются в отношении расходов на освоение природных ресурсов, осуществленных после 1 января 2011 года (пункт 10 статьи 10 Федерального закона от 27.07.2010 N 229-ФЗ). ------------------------------------------------------------------ В случае, если по результатам конкурса (аукциона) налогоплательщик не заключает лицензионное соглашение на право пользования недрами (не получает лицензию), то расходы, осуществленные в целях приобретения лицензии, включаются в состав прочих расходов с 1-го числа месяца, следующего за месяцем проведения конкурса (аукциона), равномерно в течение двух лет. В случае, если после осуществления предварительных расходов, осуществленных в целях приобретения лицензии, налогоплательщик принимает решение об отказе от участия в конкурсе (аукционе) либо о нецелесообразности приобретения лицензии, то указанные расходы также включаются в состав прочих расходов с первого числа месяца, следующего за месяцем, в котором налогоплательщиком принято указанное решение, равномерно в течение двух лет. При этом указанное решение оформляется соответствующим приказом (распоряжением) руководителя. (в ред. Федерального закона от 27.07.2010 N 229-ФЗ) В аналогичном порядке учитываются расходы, осуществленные в целях приобретения лицензий на право пользования недрами, в случае, если указанные лицензии выдаются налогоплательщику без проведения конкурсов. 2. Расходы на освоение природных ресурсов, предусмотренные пунктом 1 статьи 261 настоящего Кодекса, отражаются в аналитических регистрах налогового учета обособленно по каждому участку недр (месторождению) или участку территории (акватории), отраженному в лицензионном соглашении налогоплательщика (лицензии на право пользования недрами). При этом в зависимости от конкретного вида расходов расходы группируются как: общие расходы по осваиваемому участку (месторождению) в целом; |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
Suppir, при таких условиях:
мое регулярное выражение почти всегда работало (не сработало бы если между комментариями появился текст из одной строки и начиящюйся не на цифру). Но дальше все усложнилось ![]() Думаю нужно начать все сначала и точно определить что может и что не может быть комментарием, если нужен именно 100%-ый результат. |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz,
Ваш первый вариант работает на 95%, но есть еще 5%, которые пока не даются. Вот оставшиеся 5% случаев (всего 3 разновидности ошибок). 1. Комментарием не может быть текст, который начинается на цифру \d открывающуюся скобку \( обозначение пункта [a-zа-я]\) а), б), с) Вот это не комментарий, потому что текст содержит строку, которая начинается на скобку. Строка со скобкой не обязательно должна быть первой. Просто если мы ее "поймали", то это уже не комментарий. -------------------------------------- В случае, если налогоплательщик заключает соглашение, договор продляется (в ред. закона N 123-ФЗ) -------------------------------------- 2. Комментарием не может быть текст, внутри которого есть пустая строка (^\s{3}\n) это точно не комментарий, а текст, потому что между строками есть одна пустая. -------------------------------------- В случае, если налогоплательщик заключает соглашение, договор продляется В случае, если налогоплательщик заключает соглашение, договор продляется -------------------------------------- а это может быть комментарием, потому что пустые строки вокруг текста -------------------------------------- В случае, если налогоплательщик заключает соглашение, договор продляется В случае, если налогоплательщик заключает соглашение, договор продляется -------------------------------------- 3. Не является комментарием текст, у которого любая строка начинается на "(Глава|Статья|Пункт) \d+[\.\)]" это не комментарий, а текст, потому что строка начинается на "Глава \d" --------------------------------------------- Глава 3. тра-та ра --------------------------------------------- По идее, все эти случаи можно отловить, если делать проверку захваченного текста дополнительной функцией. Вот только как запустить эту проверку из регулярного выражения... Это сообщение отредактировал(а) Suppir - 11.2.2011, 19:26 |
|||
|
||||
DurRandir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 14 Всего: 17 |
>Вот только как запустить эту проверку из регулярного выражения...
Это то как раз просто, s/.../func($1)/e, func() возвращает то, что должно быть вставлено вместо выделения - либо $1 целиком, либо пустую строку. Но, вообще, написать для этой задачи потоковый (построчный) парсер гораздо быстрее, чем писать сложное и 95%-ное регулярное выражние. Почему таким способом не любят решать подходящие задачи - мне непонятно ![]() |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
DurRandir,
я уже написал потоковый парсер. Даже два ![]() Это сообщение отредактировал(а) Suppir - 11.2.2011, 19:48 |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
Не получилось \s* засунуть в основное выражение. У меня работает при условии что комментарий: 1. начинается и заканчивается строкой из "-". 2. состоит из 1 и более строк. 3. каждая строка не начинается с цифры, скобки, слов "Глава" и "Статья". 100% не гарантирую, мог где-то принять комментарий за обычный текст. Это сообщение отредактировал(а) alezzz - 11.2.2011, 20:44 |
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Уже гораздо лучше!
Я на выходных допишу парсер, чтобы все моменты учитывал, и выложу вместе с текстом, чтобы вы могли заценить! |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
Вспомнил про атомарную группировку, засунул \s* в основное выражение:
|
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
alezzz,
можете потестировать парсер: http://zalil.ru/30496543 (3 мегабайта) Правильно определяет > 99% комментариев. ![]() Единственный момент - работает не так быстро, как хотелось бы. В архиве приложен небольшой исходный файл, а на деле придется парсить файлы по 2 - 3 Гб. Добавлено @ 20:24 Если есть какие-то идеи, как можно ускорить скрипт, буду рад! ![]() Это сообщение отредактировал(а) Suppir - 12.2.2011, 20:25 |
|||
|
||||
alezzz |
|
|||
![]() сплю... ![]() ![]() Профиль Группа: Участник Сообщений: 499 Регистрация: 17.8.2009 Репутация: 1 Всего: 14 |
Это сколько если в цифрах? У меня на обработку файла из архива (14 Мб после распаковки) ушло 3 секунды, точно не замерял. Проверял на: Pentium 1.4 GHz 512 Mb RAM FreeBSD 7.1 Perl 5.8.8 (не обновлял, с диска) И еще вопрос, что должно совпасть тут:
|
|||
|
||||
Suppir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 588 Регистрация: 20.4.2009 Репутация: нет Всего: нет |
Это выражение с успехом заменяет следующее: "|(?:Статья|Пункт|Глава) \d+\.(\d+\.)? )|Раздел [XХVICСL\d]+\.) Т.е. 1) текст не может начинаться на кавычку 2) в начале текста (первые 13 символов) обязательно должна быть точка, после которой идет пробел: Статья 1. Пункт 1. Глава 1. Раздел XI. Если точки с пробелом нет, то, скорее всего, это комментарий. Насчет скорости: на 3 Гб файле у меня работает около 10 минут. А хотелось бы побыстрее, если возможно. Это сообщение отредактировал(а) Suppir - 13.2.2011, 14:05 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Perl" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |