Применение регулярных выражений

Автор Jako, 24 февраля 2014, 15:08

0 Пользователи и 1 гость просматривают эту тему.

Jako

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

celler

Может я ошибаюсь, но во Writer невозможно при использовании регулярных выражений перепрыгнуть через знак конца абзаца, поэтому ничего не получится. Поищите в сети текстовый редактор Atlantis Nova старых версий, например v1.0.0.68 (новее стали платными), в нём такая задача решается за несколько секунд.

JohnSUN

Был бы образец текста - было бы проще...
Что такое"выделены отступом"? Отступ, как формат абзаца, или отступ с помощью пробелов, или отступ с помощью табуляции?..
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Jako

Цитата: JohnSUN от 24 февраля 2014, 21:18Что такое"выделены отступом"?

Это значит, что выглядит как в PDF-оригинале, то есть абзацы визуально различимы по отступам 1-й строки. Они (отступы) отображаются на гор. линейке и управляемы с нее (верхний ползунок). Открыл стиль, там вроде отступы нулевые. Единственное, что в стиле вижу, это "Включить этот абзац в нумерацию строк", - может это оно? Что не пробелы, это точно.

JohnSUN

Нет, всё равно по словесному описанию трудно... Хотя бы половинку страницы с образцом текста к сообщению приложи, пожалуйста (кнопка Выберите файл под окном с текстом сообщения)
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Jako

Прикрепил кусок.

[вложение удалено Администратором]

JohnSUN

#6
Н-да, задачка... И много текста получилось? Как он был получен вообще? Из Ридера через "Сохранить текст"?

Впрочем, не важно... На твоём образце вот этот макрос отработал нормально:

Sub glueLines
Dim oText As Variant ' Весь контент текущего документа
Dim oEnum As Variant ' Перечень имеющихся абзацев
Dim oNxtPar As Variant ' Очередной, обрабатываемый абзац
Dim tNxtPar As String ' Текст, содержимое очередного абзаца (для анализа)
Dim tNewPar As String ' Текст, собранный из нескольких абзацев (для вставки в новый документ)
Dim nFLIndent As Long ' Отступ первой строки (единственный признак, по которому отбираются "настоящие" абзацы)
Dim oDoc As Variant ' Новый документ, куда попадёт результат работы макроса
Dim oDTxt As Variant ' Весь контент нового документа
Dim oDCurs As Variant ' Курсор нового документа (чтобы быстро перепрыгивать в конец текста)

GlobalScope.BasicLibraries.isLibraryLoaded("Tools")
oText = ThisComponent.getText() ' Получить весь текст текущего документа
oEnum = oText.createEnumeration() ' "Пересчитать" его абзацы
oDoc = OpenDocument("private:factory/swriter", Array())
oDTxt = oDoc.getText()
  oDCurs = oDTxt.createTextCursorByRange(oDoc.getCurrentController.getViewCursor().getEnd())
tNewPar = ""
While oEnum.hasMoreElements() ' По всем абзацам, с первого и до последнего
oNxtPar = oEnum.nextElement() ' Очередной абзац
tNxtPar = oNxtPar.getString() ' Его содержимое
nFLIndent = oNxtPar.ParaFirstLineIndent ' Размер его "красной строки" (для продолжений абзаца = 0)
If nFLIndent > 0 Then ' Начать новый абзац (сбросить в новый документ накопленный текст)
  oDCurs = oDTxt.createTextCursorByRange(oDoc.getCurrentController.getViewCursor().getEnd())
  oDTxt.insertControlCharacter(oDCurs, com.sun.star.text.ControlCharacter.LINE_BREAK, False)
oDTxt.insertString(oDCurs, tNewPar, FALSE)
tNewPar = ""
EndIf
REM Чтобы потом не вылавливать знаки переносов по всему тексту, избавимся от них прямо сейчас
REM "Переносом" считаем тире, перед которым не пробел.
If (Right(tNxtPar, 2) = "- ") AND (Right(tNxtPar, 3) <> " - ") Then tNxtPar = Left(tNxtPar, Len(tNxtPar) - 2)
tNewPar = tNewPar + tNxtPar
Wend
REM И сбросить последнюю накопленную информацию
oDCurs = oDTxt.createTextCursorByRange(oDoc.getCurrentController.getViewCursor().getEnd())
oDTxt.insertControlCharacter(oDCurs, com.sun.star.text.ControlCharacter.LINE_BREAK, False)
oDTxt.insertString(oDCurs, tNewPar, FALSE)
oDTxt.insertControlCharacter(oDCurs, com.sun.star.text.ControlCharacter.LINE_BREAK, False)
End Sub
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Jako

#7
Цитата: JohnSUN от 25 февраля 2014, 15:51
Н-да, задачка... И много текста получилось? Как он был получен вообще? Из Ридера через "Сохранить текст"?
Adobe? - Нет. Так тоже пробовал, там вообще каждое слово как новый абзац получается. ))) Просто через онлайн-конвертор прогнал, теперь хочется как-то удобочитаемый слепить, чтобы в читалку закачать (pdf-ы на ней не очень удобны). А что делать с макросами? Я в них ничего не смыслю. Я кажется подобное делал в "Альт.Поиск-замене", но не помню как.

JohnSUN

Цитата: Jako от 25 февраля 2014, 18:35
теперь хочется как-то удобочитаемый слепить, чтобы в читалку закачать (pdf-ы на ней не очень удобны).
Насчет чтения PDF'ов в читалке - +1!
Где-то когда-то видел конвертилку текстов с Lib.ru... Но она ориентировалась на "отступы пробелами", для твоего формата файла не подойдёт.
Цитата: Jako от 25 февраля 2014, 18:35
А что делать с макросами? Я в них ничего не смыслю.
Открываешь свой "неправильный" документ, жмёшь Alt+F11. Выделяешь библиотеку Standard или в разделе "Мои макросы" или в текущем документе и жмёшь кнопку "Создать". Соглашаешься с предложенным именем нового модуля и открывается окно редактирования макросов с уже готовой процедурой-пустышкой Main. Вместо неё вставляешь текст с форума. Жмёшь F5 - макрос запускается... Или переключаешься обратно на исходный документ, жмёшь Alt+F11, выбираешь библиотеку Standard, выбираешь модуль, выделяешь макрос с именем glueLines и жмёшь !"Выполнить" (или просто нажимаешь Enter)

А кстати, что-то я в нашем ЧАВО не нашел статьи "И что с этим текстом делать?"

[вложение удалено Администратором]
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

celler

А вот интересно, почему всё-таки не сделают в открытых офисах возможность использования знака конца параграфа в регулярных выражениях? Это была бы чрезвычайно полезная функция. Я только из-за этой функции уже лет 10 держу у себя на компьютере вышеупомянутый Atlantis, который кстати всего 442 килобайта размером, и пользуюсь им очень часто. Вместо вот таких сложных макросов, я для этого образца текста просто сделал несколько замен в нём и получил готовый текст, потратив на всё секунд десять. В нём, кстати, даже набирать регулярные выражения не нужно, их можно просто выбирать. Вот бы в LibreOffice иметь такое же.

[вложение удалено Администратором]

JohnSUN

#10
Цитата: celler от 25 февраля 2014, 20:15
...почему всё-таки не сделают в открытых офисах возможность использования знака конца параграфа в регулярных выражениях?
Извини, не понял... Знак доллара $ в поле Найти и сочетание \n в поле Заменить на - это он и есть. В справке, в разделе Список регулярных выражений (быстро находится по ссылке из страницы справки, которая открывается из окна Поиск и замена по кнопке Справка) так и пишут:
Цитировать\n
Представление разрыва строки, вставленного с помощью комбинации клавиш SHIFT+ВВОД. Чтобы изменить разрыв строки на разрыв абзаца, введите \n в поля Найти и Заменить на и выполните поиск и замену.
\n в текстовом поле Поиск означает разрыв строки, вставленный с помощью комбинации клавиш Shift+Enter.
\n в текстовом поле Заменить означает разрыв абзаца, который можно ввести с помощью клавиши Enter или Return.
Другое дело, что именно к этому образцу текста замену конца абзаца на что-то другое не получалось прикрутить...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Jako

Цитата: JohnSUN от 25 февраля 2014, 19:07
Открываешь свой "неправильный" документ, жмёшь Alt+F11
Пишет ошибку. Может неправильно ввел...

[вложение удалено Администратором]

celler

JohnSUN
Я это тоже читал, но у меня не получилось сделать замены, например двух концов абзаца подряд на один конец абзаца. Или например заменить конец абзаца с последующим пробелом на просто пробел. Или вот для вышевыложенного образца текста нужно сделать всего две замены:
"точка-пробел-конец абзаца" заменить на "точка-конец абзаца"
"пробел-конец абзаца" заменить на "пробел"
(можно ещё сразу избавиться от знаков переноса, но это не важно). Как это сделать в LO?
Насколько я понял, в LO можно заменять что-нибудь привязанное к знаку конца абзаца, но сам этот знак удалить или поменять на что-нибудь не получится. А вот в Атлантисе можно делать всё что угодно хоть с разрывами абзацев, хоть с разрывами страниц, хоть с концами параграфов и со многим другим.

JohnSUN

Цитата: Jako от 25 февраля 2014, 21:49
Пишет ошибку. Может неправильно ввел...
Правильно, правильно! Это я лопухнулся - скопипастил строку и не проверил, что скопипастил...
Настоящая ошибка на три строки выше: вместо функции isLibraryLoaded должна быть процедура LoadLibrary.
Эта строка должна загрузить стандартную библиотеку Tools, функцию из которой OpenDocument используем как раз в той строке, на которую пожаловался Бэйсик.
После изменения строка должна стать такой:
GlobalScope.BasicLibraries.LoadLibrary("Tools")
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Jako

Да, на раб. копии попробовал, кажется работает. Меняет их на Shift+Enter. Спасибо всем за советы! Завтра рассмотрю поподробнее эти результаты. Кстати, Спасибо celler за совет, похоже хорошая программка, в ней даже кажется epub можно делать. Такую даже не жалко и прикупить (после испытаний).