Очистка текста - в помощь копирайтеру

24.06.18

Разработка - Математика и алгоритмы

В этой статье я приведу пример написания небольшой обработки, для облегчения вычищения мусора из текста. Статья подойдет начинающим копирайтерам, рерайтерам и просто людям, регулярно работающим с большими текстами.

Просьба строго не судить за описанный в этой статье код. Код, возможно, будет интересен начинающим программистам 1С или VBA и совсем не интересен профессионалам. 

Начну сразу с постановки задачи

Пусть у Вас имеется текст достаточно большого объёма, который необходимо очистить от мусорных знаков. Делается это с помощью  обычной текстовой замены. Ниже таблица какой текст нам необходимо заменить:

Изначально ищем такой текст

Делаем замену на этот текст

Два или более переноса новой строки

Один перенос строки

Пробел + Знак препинания

Знак препинания

Буква + Знак препинания + Буква

Буква + Знак препинания + Пробел + Буква

Несколько пробелов подряд

Один пробел

Пробел + Служебный знак

Служебный знак

Пробел + Закрывающаяся скобка

Закрывающаяся скобка

 

Где знаки препинания это - !?;:,.

Закрывающаяся скобка - )]>}

Служебный знак это - +-=

Если сложить все возможные вариации знаков для поиска, их получается очень много и делать такие замены вручную, то это буквально "Мартышкин труд".

Я обычно тестирую на текстовых файлах пять - семь мегабайт, - поверьте это достаточно большие объёмы текста. После такой "чистки" вставляю в программы проверки синтаксических ошибок (например, "ОРФО") и далее выкладывается на сайты, или конвертируется в другие файлы -  FB Reader, Microsoft Word. Обычный Microsoft Word очень часто отключает проверку ошибок на больших текстах, из-за их громадного количества, поэтому прежде чем вставлять Ваш текст в любую другую программу, нужно очистить обязательный мусор.

Вообще ранее у меня был написан код на VBA для MS Word, но я сильно удивился, что код написанный на 1С при обработке одного и того же текста отрабатывал на домашнем компьютере быстрее. Может, конечно код рознится, но в целом смысл тот же, далее по тексту я приведу и код на VBA.

Собственно реализация алгоритма на 1С сводится к созданию массива из знаков подстановки с дальнейшей заменой каждого из этих знаков на более подходящий. Создадим внешнюю обработку, с одним единственным реквизитом "Текст", строка неограниченной длинны. Затем создадим форму и выведем этот реквизит на форму.

Откроем форму  в конфигураторе реквизиту "Текст" проставим свойство вид - Поле ввода. Далее добавим реквизит формы "РасставлятьЗН" тип Булево, свойство Заголовок - Расставлять правильно пробелы между знаками препинания. Так же создадим команду "Чистка текста", на клиенте.

Затем перейдём на вкладку Модуль, для редактирования модуля формы.  И отредактируем текст процедуры ЧисткаТекста():


&НаКлиенте

Процедура ЧисткаТекста(Команда)
              

Если ЭтаФорма.РасставлятьЗН = Истина Тогда
    ЗаменаЗнака = Новый Массив;         

                ЗаменаЗнака.Добавить(".");
                ЗаменаЗнака.Добавить(",");
                ЗаменаЗнака.Добавить("!");
                ЗаменаЗнака.Добавить("?");
                ЗаменаЗнака.Добавить(":");
                ЗаменаЗнака.Добавить(";");
                ЗаменаЗнака.Добавить("-");
                ЗаменаЗнака.Добавить("+");
                ЗаменаЗнака.Добавить("=");


                Для Каждого СтрокаПоискаЗН Из ЗаменаЗнака Цикл
                ТекстЗаменыЗН = " " + СтрокаПоискаЗН + " ";
                Объект.Текст = СтрЗаменить(Объект.Текст, СтрокаПоискаЗН, ТекстЗаменыЗН);
                КонецЦикла;
                ЗаменаЗнака.Очистить();

    КонецЕсли;

                Замена = Новый Массив;
                Замена.Добавить(Символы.ПС+Символы.ПС+Символы.ПС+Символы.ПС);
                Замена.Добавить(Символы.ПС+Символы.ПС+Символы.ПС);
                Замена.Добавить(Символы.ПС+Символы.ПС);
                Замена.Добавить("    ");
                Замена.Добавить("   ");
                Замена.Добавить("  ");
                Замена.Добавить(" .");
                Замена.Добавить(" ,");
                Замена.Добавить(" !");
                Замена.Добавить(" ?");
                Замена.Добавить(" )");
                Замена.Добавить(" ]");
                Замена.Добавить(" }");
                Замена.Добавить(" >");
                Замена.Добавить(" ;");
                Замена.Добавить(" :");


                Для Каждого СтрокаПоиска Из Замена Цикл
                ТекстЗамены = Прав(СтрокаПоиска, 1);
                Объект.Текст = СтрЗаменить(Объект.Текст, СтрокаПоиска, ТекстЗамены);
                КонецЦикла;
                Замена.Очистить();



КонецПроцедуры

Далее просто заходим в 1С: Предприятие любой конфигурации на управляемых формах. Открываем обработку из Меню -> Файл открыть.

Принцип работы обработки простой - вставляете не отформатированный текст в поле "Текст" и нажимаете на кнопку "Очистка текста". После того как поле "Текст" станет доступно (у меня на компьютере это пара секунд) из этого же поля можно скопировать готовый обработанный текст.

Используйте обработку 1С для работы с обычным текстом простых кодировок, а вот если исходный тест "набит" под завязку спец символами (рожицы, крышечки, смесь символов Unicode), то лучше использовать макрос VBA для Word.

Как видите всё работает достаточно примитивно. Создаем массив элементов поиска для замены, потом из каждого элемента получаем строку замены и подставляем в типовую функцию СтрЗаменить.

Поскольку используются функции языка 1С прекрасно работающие &НаКлиенте, мы можем обойтись без серверного вызова.

Если вы планируете использовать обработку 1С постоянно и в типовых конфигурациях. То в модуль объекта добавьте код для регистрации этой обработки.

 
 Код для регистрации

 

Далее речь пойдет о макросе написанном на Visual Basic Application.

Для проекта VBA в Microsoft Office 2007 Pro я создал форму с кнопкой CommandButton1, чекбоксами Check1, Check2, Check3, Check4, Check5, Check6, Check7 и комбобокс ComboBox1 для выбора. Работает помедленнее, зато ещё умеет выравнивать шрифт, поля документа, выравнивает абзацы  и меж строчный интервал. Естественно для работы нужно разрешить работу макросов Word.

Исходный код формы:

Private Sub CommandButton1_Click()

With ActiveDocument.Styles(wdStyleNormal).Font
        If .NameFarEast = .NameAscii Then
            .NameAscii = ""
        End If
        .NameFarEast = ""
    End With
    With ActiveDocument.PageSetup
        .LineNumbering.Active = False
        .Orientation = wdOrientPortrait
        .TopMargin = CentimetersToPoints(1)
        .BottomMargin = CentimetersToPoints(1)
        .LeftMargin = CentimetersToPoints(1)
        .RightMargin = CentimetersToPoints(1)
        .Gutter = CentimetersToPoints(0)
        .HeaderDistance = CentimetersToPoints(1.25)
        .FooterDistance = CentimetersToPoints(1.25)
        .PageWidth = CentimetersToPoints(21)
        .PageHeight = CentimetersToPoints(29.7)
        .FirstPageTray = wdPrinterDefaultBin
        .OtherPagesTray = wdPrinterDefaultBin
        .SectionStart = wdSectionNewPage
        .OddAndEvenPagesHeaderFooter = False
        .DifferentFirstPageHeaderFooter = False
        .VerticalAlignment = wdAlignVerticalTop
        .SuppressEndnotes = False
        .MirrorMargins = False
        .TwoPagesOnOne = False
        .BookFoldPrinting = False
        .BookFoldRevPrinting = False
        .BookFoldPrintingSheets = 1
        .GutterPos = wdGutterPosLeft
    End With

   Selection.EndKey Unit:=wdStory, Extend:=wdExtend
   If ComboBox1.ListIndex = 0 Then
    Selection.Font.Name = "Times New Roman"
    Selection.Font.Size = 12
    Selection.Font.Color = wdColorBlack
    ElseIf ComboBox1.ListIndex = 1 Then
    Selection.Font.Name = "Courier New"
    Selection.Font.Size = 12
    Selection.Font.Color = wdColorBlack
    ElseIf ComboBox1.ListIndex = 2 Then
    Selection.Font.Name = "Arial"
    Selection.Font.Size = 12
    Selection.Font.Color = wdColorBlack
    Else
   
    End If

    With Selection.ParagraphFormat
        .LeftIndent = CentimetersToPoints(0)
        .RightIndent = CentimetersToPoints(0)
        .SpaceBefore = 0
        .SpaceBeforeAuto = False
        .SpaceAfter = 0
        .SpaceAfterAuto = False
        .LineSpacingRule = wdLineSpaceMultiple
        .LineSpacing = LinesToPoints(1)
        .Alignment = wdAlignParagraphLeft
        .WidowControl = True
        .KeepWithNext = False
        .KeepTogether = False
        .PageBreakBefore = False
        .NoLineNumber = False
        .Hyphenation = True
        .FirstLineIndent = CentimetersToPoints(0)
        .OutlineLevel = wdOutlineLevelBodyText
        .CharacterUnitLeftIndent = 0
        .CharacterUnitRightIndent = 0
        .CharacterUnitFirstLineIndent = 0
        .LineUnitBefore = 0
        .LineUnitAfter = 0
        .MirrorIndents = False
        .TextboxTightWrap = wdTightNone
    End With

   Selection.Find.ClearFormatting
   Selection.Find.Replacement.ClearFormatting

    With Selection.Find
    If FormReplaser.Check1.Value = True Then
        .Text = "  "
        .Replacement.Text = " "
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    If FormReplaser.Check2.Value = True Then
        .Text = " ."
        .Replacement.Text = "."
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    If FormReplaser.Check3.Value = True Then
        .Text = " ,"
        .Replacement.Text = ","
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    If FormReplaser.Check4.Value = True Then
        .Text = " !"
        .Replacement.Text = "!"
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    If FormReplaser.Check5.Value = True Then
        .Text = " ?"
        .Replacement.Text = "?"
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    If FormReplaser.Check6.Value = True Then
        .Text = " )"
        .Replacement.Text = ")"
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    If FormReplaser.Check7.Value = True Then
        .Text = " ]"
        .Replacement.Text = "]"
        .Forward = True
        .Wrap = wdFindContinue
         Selection.Find.Execute Replace:=wdReplaceAll
    End If

    End With
    
End Sub
Private Sub UserForm_Initialize()
FormReplaser.Check1.Value = True
FormReplaser.Check2.Value = True
FormReplaser.Check3.Value = True
FormReplaser.Check4.Value = True
FormReplaser.Check5.Value = True
FormReplaser.Check6.Value = True
FormReplaser.Check7.Value = True

ComboBox1.AddItem "Исправить шрифт на Times New Roman, 12, черный"
ComboBox1.AddItem "Исправить шрифт на Courier New, 12, черный"
ComboBox1.AddItem "Исправить шрифт на Arial, 12, черный"
ComboBox1.AddItem "Оставить исходный шрифт"
ComboBox1.ListIndex = 0
End Sub
 
 Принцип работы обработки на VBA немного отличается:

 

Поскольку код на VBA был написан достаточно давно, я не стал его переписывать. Думаю, что переписать его на подобии того, как работает в 1С можно, просто пока не возникла необходимость в этом. Алгоритм тот же, просто используется прямая замена для введенных вручную строковых величин, а не перебирается массив элементов, но по своей сути работает абсолютно одинаково.
 
Если вы занимаетесь подготовкой текстов профессионально, тогда можете написать в комментарии какие приёмы используете самостоятельно и как автоматизируете свой труд.

Обработка копирайтер рерайтер текст замена VBA Word мусор очистка

См. также

Метод Дугласа-Пойкера для эффективного хранения метрик

Математика и алгоритмы Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    1886    stopa85    12    

34

Алгоритм симплекс-метода для решения задачи раскроя

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    4687    user1959478    50    

34

Регулярные выражения на 1С

Математика и алгоритмы Инструментарий разработчика Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    7687    4    SpaceOfMyHead    17    

56

Мини-обзор разных решений задач

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    3115    RustIG    6    

25

Модель распределения суммы по базе

Математика и алгоритмы Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    7952    7    kalyaka    11    

44

Изменения формата файлов конфигурации (CF) в 8.3.16

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Дополнение по формату файлов конфигурации (*.cf) в версии 8.3.16.

16.12.2021    4565    fishca    13    

36

Интересная задача на Yandex cup 2021

Математика и алгоритмы Бесплатно (free)

Мое решение задачи на Yandex cup 2021 (frontend). Лабиринт. JavaScript.

12.10.2021    8957    John_d    73    

46
Оставьте свое сообщение