Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Python
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.10.2023, 06:50   #31
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
скопировать и сохранить в текстовом виде, тогда будет 27073 строки, может скрипту будет легче?
Может быть. Взял код из 28 сообщения, и только читал вордовский документ, а писал в html. Тогда выделение буквы "а" стало занимать 0.7 секунд.
Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
код оптимальный?, или можно его поправить?
Подготовка текста нормальная, но поиск подстроки в таком огромном тексте все равно "недешевый".
Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
Pattern matching
Согласен с p51x, что эта фича совсем не для поиска, а просто навороченный switch-case для более компактного написания кода.

Вот такой прототип (docx документ только читается, а результат пишется в новый html; отказ от регулярок в пользу префиксных деревьев):
Код:
from docx import Document
import re
from datetime import datetime
from codecs import open

END = object()
    
class Keywords(object):

    def __init__(self):
        self.trie = dict()

    def add(self, word):
        current_dict = self.trie
        for c in word:
            current_dict = current_dict.setdefault(c, {})
        current_dict[END] = END

    def finditer(self, text):
        current_dict = self.trie
        start = 0
        idx = 0
        text_len = len(text)

        while idx < text_len:
            if END in current_dict:
                yield start, idx
                current_dict = self.trie
                start = idx

            char = text[idx]
            if char in current_dict:
                current_dict = current_dict[char]
                idx += 1
            else:
                current_dict = self.trie
                idx = start + 1
                start = idx

        if idx == text_len and END in current_dict:
            yield start, text_len

def main():
    date_start = datetime.now()
    highlights = 0

    d = Document('война и мир.docx')

    '''
    # 10000 "слов" из текста
    s = set()
    for paragraph in d.paragraphs:
        text = paragraph.text
        if not text:
            continue
        s.update([t.lower() for t in text.split(" ")])
    if '' in s:
        s.remove('')
    print(len(s))
    with open("some_dict.txt", "w") as f:
        f.write('\n'.join(list(s)[:10000]))
    exit()
    '''

    with open("some_dict.txt", "r") as f:
        vFindText = f.read().split('\n')

    k = Keywords()
    for word in vFindText:
        k.add(word)

    # reg = re.compile("|".join(map(re.escape, vFindText)))

    with open("война и мир-highlightened.html", "w") as f:
        f.write('<!DOCTYPE html>\n<html>\n<body>\n')

        for paragraph in d.paragraphs:
            text = paragraph.text
            if not text:
                continue

            f.write('<p>')
            last_idx = 0
            # for match in reg.finditer(text):
            #     highlights += 1
            #     start, end = match.start(), match.end()
            for start, end in k.finditer(text):
                highlights += 1
                if start > last_idx:
                    f.write(text[last_idx:start])
                last_idx = end
                f.write('<span style="color: #ff0000;">' + text[start:end] + '</span>')
            if last_idx != len(text):
                f.write(text[last_idx:])
            f.write('</p>\n')

        f.write('</body>\n</html>\n')

    date_end = datetime.now()
    print('Начато: ', date_start, '\nЗакончено: ', date_end, '\nСекунд: ', (date_end - date_start).total_seconds(),'\nВыделения: ', highlights)

if __name__ == "__main__":
    main()
Для ознакомления: Префиксное дерево (trie). Код Keywords вдохновлен flashtext, но сильно упрощен. Закомментирован код получения списка "слов" для выделения. В таком виде 10000 "слов" в Войне и Мире (примерно 2млн символов) выделяются за 2 секунды, но не представляю, что будет с вашим количеством замен и размером текста.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 26.10.2023, 15:14   #32
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
не представляю, что будет с вашим количеством замен и размером текста
пока тоже....
решил сделать калоборацию вба+питон
питон из 1 млн кандидатов на замены делает список из 100% кандидатов их получается чуть более 30000 шт. и тратит на это 4 часа, потом он их пишет в файл, а потом подключается вба:
Код:
Option Explicit
Sub Замена_текста_с_нужным_цветом_шрифта_финиш()

Dim Startt As Date
Startt = VBA.Time$
Dim i As Long
Dim File As String
Dim CF As String
'имя файла и пyть к нему
File = "I:\replaces\lst_replace_in_doc.js"
'откpыть файл для чтения
Open File For Binary As #1
'вcё cодеpжимое файла
CF = Input(FileLen(File), 1)
'закpыть файл
Close #1
Dim vFindText As Variant
vFindText = Array(CF)
 
'избавляемся от всех полей=сначала выделяем весь документ Конрол+A, затем Конрол+Шифт+Эф9
ActiveDocument.Range.Fields.Unlink
'шрифт всего документа окрасить в чёрный цвет
ActiveDocument.Range.Font.ColorIndex = wdBlack
For i = 0 To UBound(vFindText)
    With ActiveDocument.Range.Find
        'искать нужное только в тексте с шрифтом чёрного цвета
        .Font.ColorIndex = wdBlack
        .Text = vFindText(i)
        Debug.Print .Text
        'окрасить нужное шрифтом красного цвета
        .Replacement.Font.ColorIndex = wdRed
        .Execute Replace:=wdReplaceAll
    End With
Next i
Dim Endd As Date
Endd = VBA.Time$
 
MsgBox$ _
"Начато: " & Startt & Chr$(13) & _
"Закончено: " & Endd
 
End Sub
Ципихович Эндрю вне форума Ответить с цитированием
Старый 27.10.2023, 08:55   #33
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

BDA для понимания, где ищу:
юридические документы, ну та же Конституция РФ и по нисходящей, кодексы, законы, указы, приказы, постановления
что ищу
юридические термины - "гражданская ответственность" и т.д.
бухгалтерские термины - "бухгалтерский учёт" и т.д.
медицинские термины - "брюшной тиф" и т.д.
бытовые "я пошел в" и т.д.
даты все в разных вариациях
меры веса, скорости, длины
они все со склонениями
понравилась мысль про Префиксное дерево (trie)
но курил его так и не понял как для моего случая это применить
можете показать пример?
сейчас я ищу в цикле
Код:
for l in vFindText:
так как in быстрее всего, конечно регулярки быстрей но хз как написать их в цикле, и мне нужно искать по принципу предварительной сортировки списка искомого по его длине и искать от самого длинного к самому короткому
Ципихович Эндрю вне форума Ответить с цитированием
Старый 27.10.2023, 12:47   #34
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

по окончанию работы мой скрипт отрапортовал:

Ошибок нет, в заменах НЕ имеется замены, где третье слово является цифрой 0-9 или знаком вопроса
Количество обработанных js файлов с заменами: 4
Количество замен во всех обработанных js файлах: 915929
Количество обработанных с документами htm файлов: 30
Количество абзацев в файле со всеми обрабатываемыми htm документами: 185467
Количество замен из текстового файла, которые имеются в doc файле: 32446
Результат работы записан в файл: i:/replaces/lst_replace_in_doc.js
Начато 2023-10-27 10:16:24.463556
Окончено 2023-10-27 14:26:09.119631
Продолжительность работы 4:09:44.656075

то что делало долго в этом случай пофиг, но для прокачки своих скилов по питону не помешало бы прокачать или префиксное дерево или регулярки.......
Ципихович Эндрю вне форума Ответить с цитированием
Старый 28.10.2023, 10:04   #35
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
а потом подключается вба:
код пришлось переделать, так как нужен утф-16, финишный код вба:
Код:
Option Explicit
Sub Замена_текста_с_нужным_цветом_шрифта_финиш()

Dim Startt As Date
Startt = VBA.Time$
Dim i As Long
Dim File As String
Dim CF As String
'имя файла и пyть к нему
File = "I:\replaces\VBA.js"
Dim nf As Long
Dim b() As Byte
nf = FreeFile
Open File For Binary As nf
ReDim b(LOF(nf))
Get #nf, , b()
CF = b()
'Debug.Print Len(CF)
CF = MidB$(CF, 3) 'отрезать первые два байта
'Debug.Print Len(CF)
'Debug.Print CF
Close #nf
Dim vFindText() As String
vFindText = Split(CF, vbCrLf)
 
'избавляемся от всех полей=сначала выделяем весь документ Конрол+A, затем Конрол+Шифт+Эф9
ActiveDocument.Range.Fields.Unlink
'шрифт всего документа окрасить в чёрный цвет
ActiveDocument.Range.Font.ColorIndex = wdBlack
For i = 0 To UBound(vFindText)
    With ActiveDocument.Range.Find
        'искать нужное только в тексте с шрифтом чёрного цвета
        .Font.ColorIndex = wdBlack
        .Text = vFindText(i)
        Debug.Print .Text
        'окрасить нужное шрифтом красного цвета
        .Replacement.Font.ColorIndex = wdRed
        .Execute Replace:=wdReplaceAll
    End With
Next i
Dim Endd As Date
Endd = VBA.Time$
 
MsgBox$ _
"Начато: " & Startt & Chr$(13) & _
"Закончено: " & Endd
 
End Sub
осталось узнать время выполнения........
Ципихович Эндрю вне форума Ответить с цитированием
Старый 28.10.2023, 11:53   #36
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
осталось узнать время выполнения........
с таким файлом
Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
Количество абзацев в файле со всеми обрабатываемыми htm документами: 185467
где 10.5 тысяч страниц
лет 100-пустая затея))=отрицательный опыт
а разбивать этот документ как он и был соединён на
Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
Количество обработанных с документами htm файлов: 30
тоже смысла нет.......
Ципихович Эндрю вне форума Ответить с цитированием
Старый 28.10.2023, 20:57   #37
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

BDA, дошли руки, до разбора Вашего последнего кода (код в сообщении № 31)
код спотыкается на строке:
Код:
  f.write(text[last_idx:])
ошибка:
Traceback (most recent call last):
File "C:\pythonProject\sudrf.ru1.py" , line 68, in <module>
main()
File "C:\pythonProject\sudrf.ru1.py" , line 61, in main
f.write(text[last_idx:])
File "C:\Users\q8902\AppData\Local\Progr ams\Python\Python311\Lib\encodings\ cp1251.py", line 19, in encode
return codecs.charmap_encode(input,self.er rors,encoding_table)[0]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'charmap' codec can't encode character '\u25e6' in position 0: character maps to <undefined>
стал смотреть, что успело записать в файл с результатом:
общая часть-ПОСЛЕДНЯЯ ЗАПИСЬ В ФАЙЛЕ
◦раздел i-ТО, ЧТО ИДЁТ СЛЕДОМ
может проблема в наличии знака "◦" как поправить код? спасибо
Ципихович Эндрю вне форума Ответить с цитированием
Старый 29.10.2023, 10:40   #38
Ципихович Эндрю
Старожил
 
Регистрация: 24.01.2011
Сообщений: 3,043
По умолчанию

Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
может проблема в наличии знака "◦" как поправить код?
ниже под строкой:
Код:
text = paragraph.text
добавил:
Код:
if text[:1] == chr(9702): text = text[1:]  # {chr(9702)} => '◦' - прозрачный маркер списка
продвинулся.........
но опять тормоз, в документе есть таблица, которая вордом была исковеркана, потому как она построена из знаков "_", "|", уголочков "┘" нужно подумать..........
Ципихович Эндрю вне форума Ответить с цитированием
Старый 01.11.2023, 02:34   #39
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
можете показать пример?
мне нужно искать по принципу предварительной сортировки списка искомого по его длине и искать от самого длинного к самому короткому
Пример с префиксным деревом в 31 сообщении, которое вы уже начали разбирать, но поиск в текущем виде находит самую короткую замену. Чтобы искать самую длинную, нужно еще утащить кода из метода extract_keywords (flashtext
/keyword.py
).
Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
а разбивать этот документ тоже смысла нет.......
Может быть и есть. Сейчас только одно ядро процессора трудится, а если разбить текст на куски и каждый кусок обрабатывать на своем ядре, то получится быстрее.
Цитата:
Сообщение от Ципихович Эндрю Посмотреть сообщение
код спотыкается на строке
Попробуйте так:
Код:
    with open("Властелин колец-highlightened.html", "w", encoding = "utf-8") as f:
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шрифт текста в файле пдф Alifhan Фриланс 2 24.08.2019 11:21
изменить шрифт detalik Помощь студентам 2 15.04.2011 16:22
Как изменить шрифт FIREVISTA Общие вопросы C/C++ 12 24.04.2010 19:08
Искаженный шрифт в скомпилированном файле справки Fantom Общие вопросы Delphi 0 19.09.2008 12:51
ШРИФТ в файле справки prog38 Помощь студентам 7 13.09.2008 08:36