Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

8 Март 2021, 08:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Доступно и просто о работе в офисных пакетах
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1 2 »   Вниз
  Печать  
Автор Тема: Поиск и замена в текстовой переменной с помощью регулярных выражений  (Прочитано 10576 раз)
0 Пользователей и 1 Гость смотрят эту тему.
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Стартовое сообщение: 6 Ноябрь 2011, 16:26 »

Добрый день!
Есть текстовая переменная
Код:
str1="RADIATION
Zalogin
21-11-2008"
Именно такая, с концами абзацев.

Вопрос в том, как с помощью регулярных выражений производить поиск и замену в этой переменной str1, т.е, например, заменить все концы абзацев на такой текст "<PARAGRAPH_BREAK>" и моместить результат в новую переменную str2?
Записан
Рыбка Рио
Форумчанин
***
Offline Offline

Сообщений: 1 678


« Ответ #1: 6 Ноябрь 2011, 20:10 »

Именно регулярные выражения? Не знаю, но в любом случае, думаю можно самим написать функцию, которая преобразует регулярные выражения в обычные. А дальше - функция Replace.

REM  *****  BASIC  *****

Sub Main
p=chr(13)
str1="RADIATION"+p+"Zalogin"+p+"21-11-2008"
str2 = Replace(str1,p,"<PARAGRAPH_BREAK>")
msgbox str2
End Sub
Записан

ubuntu 12.04 + LibO3.6.0
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Ответ #2: 7 Ноябрь 2011, 10:59 »

Вопрос касался именно регулярных выражений в текстовой переменной.

Но и ответ Клио неверный.

Windows и Linux сильно отличаются в этом плане.

PARAGRAPH_BREAK:
Windows - Chr(13) & Chr(10)
Linux - Chr(10) (Непонимающий)

LINE_BREAK:
Windows - Chr(10)
Linux - Chr(10) (Непонимающий)

Для иллюстрации сказанного прикладываю тестовый файл с разными вариантами Replace.

Если внимательно их проверить, то видно, что только в Windows результаты соответствуют ожидаемым.


PS. И сразу вопрос. Как написать макрос, работающий одинаково в Windows  и Linux?


[вложение удалено Администратором]
« Последнее редактирование: 7 Ноябрь 2011, 11:02 от neft » Записан
bormant
Глобальный модератор
*
Offline Offline

Сообщений: 939



« Ответ #3: 7 Ноябрь 2011, 11:03 »

neft,
на такой текст "<PARAGRAPH_BREAK>"
PARAGRAPH_BREAK:
Windows - Chr(13) & Chr(10)
Linux - Chr(10)

LINE_BREAK:
Windows - Chr(10)
Linux - Chr(10)

Условия задачи меняются на ходу.
Записан

Автору на яд. Поддержать форум.
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Ответ #4: 7 Ноябрь 2011, 11:13 »

Мне Клио сам предложил сменить задачу на Replace.
А там проблемы.
Записан
bormant
Глобальный модератор
*
Offline Offline

Сообщений: 939



« Ответ #5: 7 Ноябрь 2011, 11:18 »

В условии были текстовые переменные, замена одного текста на другой.
Потом выясняется, что не текстовые переменные, а документ; замена не на текст, а вставка управляющих последовательностей; ещё что-то?

Если надеялись, что ThisComponent.getText().String отдаст все особенности текста документа -- зря, это только наиболее близкое текстовое представление, как уже убедились, не совсем полное, в частности, разрывы строк становятся неотличимы от конца абзаца.

Так что, с решаемой задачей всё же нужно определиться...
« Последнее редактирование: 7 Ноябрь 2011, 11:22 от bormant » Записан

Автору на яд. Поддержать форум.
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Ответ #6: 7 Ноябрь 2011, 11:21 »

В Windows ThisComponent.getText().String отдает все особенности текста документа!!!

В Linux - полная ерунда!!!
Записан
bormant
Глобальный модератор
*
Offline Offline

Сообщений: 939



« Ответ #7: 7 Ноябрь 2011, 11:35 »

Скажем так, в версии OOo под Windows значение, возвращаемое ThisComponent.getText().String позволяет отличить разрыв строки от разрыва абзаца, поскольку первый представляет как chr(10), а второй как chr(13)&chr(10). В версии OOo под Linux оба представлены как chr(10).

Тем не менее, возвращаемое под Win от этого не становится меньшей ерундой. Смотреть в сторону разделителей строк, принятых в Windows/Unix/Mac, стандарта ASCII.
Одиночный chr(10) -- LF -- Line Feed -- прогон строки -- никогда не использовался в качестве общепринятого разрыва строки в DOS/Windows.
Записан

Автору на яд. Поддержать форум.
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Ответ #8: 7 Ноябрь 2011, 11:48 »

В версии OOo под Linux оба представлены как chr(10).
Вот это и мешает их разделить, если нужно. Ведь в ООо они разделены.
Записан
Рыбка Рио
Форумчанин
***
Offline Offline

Сообщений: 1 678


« Ответ #9: 8 Ноябрь 2011, 20:44 »

Если длина текста более кажется 64000 знаков, то
Код:
msgbox ThisComponent.Text.String
выдаст пустую строку.
С помощью метода gotoNextParagraph можно считывать параграфы,
Код:
TK = ThisComponent.Text.createTextCursor()
TK.gotoStart(false)
TK.gotoNextParagraph(true)
msgbox TK.String
и суммировать их, вставляя между ними <PARAGRAPH_BREAK>
Записан

ubuntu 12.04 + LibO3.6.0
Рыбка Рио
Форумчанин
***
Offline Offline

Сообщений: 1 678


« Ответ #10: 8 Ноябрь 2011, 21:00 »

(хотя с переходом к сдедующему параграфу не совсем так, извините, есть ещё gotoStartOfParagraph, gotoEndOfParagraph ...)
Записан

ubuntu 12.04 + LibO3.6.0
Рыбка Рио
Форумчанин
***
Offline Offline

Сообщений: 1 678


« Ответ #11: 8 Ноябрь 2011, 23:23 »

О! А можно ещё проще:
Код:
REM  *****  BASIC  *****

Sub Main
Doc = ThisComponent
SD = Doc.createSearchDescriptor()
SD.SearchRegularExpression = TRUE
SD.SearchString = ".+"
Results = Doc.findAll(SD)
str1=""
For i=0 to Results.Count-1
str1=str1+Results(i).String+"<PARAGRAPH BREAK>"
Next
msgbox str1
End Sub
Записан

ubuntu 12.04 + LibO3.6.0
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Ответ #12: 9 Ноябрь 2011, 10:21 »

Этот вариант смешивает "конец абзаца" и "конец строки" в одну кучу, а это неправильно.
LINE_BREAK != PARAGRAPH_BREAK
« Последнее редактирование: 9 Ноябрь 2011, 10:23 от neft » Записан
Рыбка Рио
Форумчанин
***
Offline Offline

Сообщений: 1 678


« Ответ #13: 9 Ноябрь 2011, 11:50 »

Тогда замените в коде ".+" на "(.|\n)+"

В итоге код может выглядеть вот так:
Код:
REM  *****  BASIC  *****

Sub Main
Doc = ThisComponent
SD = Doc.createSearchDescriptor()
SD.SearchRegularExpression = TRUE
SD.SearchString = "(.|\n)+"
Results = Doc.findAll(SD)
str1=""
stmp=""
For i=0 to Results.Count-1
stmp = Replace(Results(i).String,chr(10),"<LINE_BREAK>")
str1=str1+stmp+"<PARAGRAPH_BREAK>"
Next
msgbox str1
End Sub
Записан

ubuntu 12.04 + LibO3.6.0
neft
Форумчанин
***
Offline Offline

Сообщений: 189


« Ответ #14: 9 Ноябрь 2011, 14:38 »

Спасибо! Вот это действительно настоящее решение!

Код:
stmp = Replace(Results(i).String,chr(10),"<LINE_BREAK>")
можно заменить на
Код:
stmp = Replace(Results(i).String,"\n","<LINE_BREAK>")

Если нужно заменить только "конец абзаца", не трогая "конец строки" (как в моей задаче), то
Код:
stmp = Results(i).String

Записан
Страниц: 1 2 »   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!