PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » поиск текста в памяти


поиск текста в памяти

Сообщений 1 страница 12 из 12

1

есть текстовой файл. в нем построчно код всякий разный. и есть 3 слова. надо проверить существуют ли эти слова в данном файле. с одной стороны можно построчно файл читать и после каждую строку по три раза гонять с findstring() с данными словами. но этож капец капецный :) занимать будет прилично времени... нет ли что-то типа findmemory? то есть сразу файл бахнуть в образ в памяти и после уже сделать поиск в этой памяти нужной строчки. точнее даже не текстовой строчки, а маленького кусочка памяти, куда вписано это слово.

у меня итак уже программа стартует не сразу, а несколько секунд раздупляется. добавлю эту проверку построчно, да еще и три раза одну и ту-же строчку проверять - будет еще тоскливее.

0

2

Файл можно открыть в память весь и искать строку в виде байтов. Можно открытое прочитать в переменную и искать строковой функцией поиска.

0

3

Попробуйте через регулярку.

Код:
; читает файл в переменную
Procedure.s Load_File_To_Var(FilePath$)
  Protected FileText$, File = ReadFile(#PB_Any, FilePath$)  
  If File  
    While Not Eof(File)
      FileText$ = ReadString(File, #PB_File_IgnoreEOL)  
    Wend
    CloseFile(File)
  EndIf
  ProcedureReturn FileText$
EndProcedure

Define TextFile$ = Load_File_To_Var( "D:\MyFile.txt" ) ; читаем весь файл в текстовую переменную

; три слова
Define NewMap Word.a()
Word("Word1")
Word("Word2")
Word("Word3")


; соберём регулярку для поиска слов
Define Pattern$, Sep$
ForEach Word()
  Pattern$ + Sep$ + MapKey( Word() )
  Sep$ = "|"
Next	

#RegEx = 0
If CreateRegularExpression(#RegEx, Pattern$) 
  If ExamineRegularExpression(#RegEx, TextFile$)
    Define Word$, i = 0
    While NextRegularExpressionMatch(#RegEx)
      Word$ = RegularExpressionMatchString(#RegEx)
      If Not Word(Word$)
        Debug "Есть слово: " + Word$
        Word() = #True
        i + 1
        If i >= MapSize( Word() )
          Break
        EndIf
      EndIf
    Wend
    If i >= MapSize( Word() )
      Debug "Все слова присутствуют в файле"
    EndIf	
  EndIf
EndIf

Отредактировано Webarion (12.08.2022 18:20:59)

0

4

Код:
Procedure FindMemoryUTF8String(*Buffer, Length, String$, Mode=#PB_String_CaseSensitive)
  StrLength = Len(String$)
  *BufferEnd = *Buffer + Length - StrLength
  While *Buffer <= *BufferEnd
    If CompareMemoryString(*Buffer, UTF8(String$), Mode, StrLength, #PB_UTF8) = 0
      ProcedureReturn *Buffer
    Else
      *Buffer + 1
    EndIf
  Wend
  ProcedureReturn 0
EndProcedure

FileName$ = "d:\testfile.txt"
hFile = ReadFile(#PB_Any, FileName$, #PB_File_SharedRead)
lFileSize = Lof(hFile)
*BufferFile = AllocateMemory(lFileSize)
ReadData(hFile, *BufferFile, lFileSize)

Debug FindMemoryUTF8String(*BufferFile, lFileSize, "Compound")

0

5

не хочет :(

проблема заключается в чем - в файле могут быть строчки типа:

Код:
icons_units_lg:	dc.l iconl_carryall

вот надо найти где именно в одну строку так написано.

а должен быть перенос на новую строчку:

Код:
icons_units_lg:
     dc.l iconl_carryall

между ": dc.l" табуляция. что просто скопировать текст как есть - он табуляцию вроде бы видит большим пробелом... или так вписать:
icons_units_lg:" + Chr(9) + "dc.l iconl_carryall
система не находит :)

а если в хекс редакторе этот документ посмотреть, то там вакханалия какая-то...

Код:
 i  c  o  :                 d  c  .  l
69 63 6F 3A 09 0D 0A 09 09 64 63 2E 6C

09 я еще понимаю - как раз моя табуляция, но что за 0D 0A 09 09 ? и как это правильно указать в качестве элемента для поиска? в смысле всё сочетание целиком вместе с этой табуляцией внутри "icons_units_lg: dc.l iconl_carryall"

Отредактировано SeregaZ (12.08.2022 20:09:33)

0

6

ааааааааа... ясно :) там и должен был быть перенос, но из-за ошибки 0D 0A - 13 и 10 это же перенос каретки на новую строчку...
поиск сделал так:

Код:
"icons_units_lg:" + Chr(9) + Chr($D) + Chr($A) + Chr(9) + Chr(9) + "dc.l iconl_carryall"

теперь находит. спасибо.

я оказывается не тот файл тестил :) сам дурак :) уже исправленный гоняю и удивляюсь почему не находит.

Отредактировано SeregaZ (12.08.2022 20:21:06)

0

7

Lin написал(а):

If CompareMemoryString(*Buffer, UTF8(String$), Mode, StrLength, #PB_UTF8) = 0

Утечки памяти и уменьшения скорости не будет?

0

8

то есть лучше UTF8(String$) заменить на заранее подготовленный кусочек памяти, куда будет вписано слово и после обязательно освободить его?

0

9

Пётр написал(а):

Утечки памяти и уменьшения скорости не будет?

это просто пример накаляканый за пару мин, а не готовый код, там еще StrLength полагаю будет неправильный если кириллицу искать

SeregaZ написал(а):

то есть лучше UTF8(String$) заменить на заранее подготовленный кусочек памяти

да, так лучше будет

SeregaZ написал(а):

но что за 0D 0A 09 09

#CRLF$ + #TAB$ + #TAB$

SeregaZ написал(а):

"icons_units_lg:" + Chr(9) + Chr($D) + Chr($A) + Chr(9) + Chr(9) + "dc.l iconl_carryall"

или вот так:

Код:
~"icons_units_lg:\t\r\n\t\tdc.l iconl_carryall"

Отредактировано Lin (12.08.2022 23:30:07)

0

10

ещё и так можно целиком файл прочесть в строку
нет надобности выделять память и нет проблемы с кодировкой
ReadData(0, *m, n) она не понимает кодировки, кажется только одну правильно читает
пришлось искать как обойти

Код:
If FileSize(mf())>0; читаем файл в строку
If ReadFile(0, mf())
; ЗВ только эти три кодировки понимает
; #PB_Ascii = 24 = ANSI, #PB_UTF8 = 2 = 65001(UTF-8), #PB_Unicode = 25 = 1200(UTF-16 LE)
f=ReadStringFormat(0)
; тут проверка кодировки
s=ReadString(0, f|#PB_File_IgnoreEOL)
CloseFile(0)
EndIf
Else
Continue
EndIf
Код:
; все встроенные строковые работают
n=CountString(s, #CRLF$)
s1=StringField(s, k, #CRLF$)

0

11

newJS написал(а):

ещё и так можно целиком файл прочесть в строку
нет надобности выделять память и нет проблемы с кодировкой
ReadData(0, *m, n) она не понимает кодировки, кажется только одну правильно читает
пришлось искать как обойти

Так у него предполагается что кодировка изначально известна?

0

12

SeregaZ написал(а):

не хочет

проблема заключается в чем - в файле могут быть ....
а если в хекс редакторе этот документ посмотреть, то там вакханалия какая-то...

09 я еще понимаю - как раз моя табуляция, но что за 0D 0A 09 09 ? и как это правильно указать в качестве элемента для поиска? в смысле всё сочетание целиком вместе с этой табуляцией внутри "icons_units_lg: dc.l iconl_carryall"

Отредактировано SeregaZ (12.08.2022 20:09:33)

Так обычное сравнение по байтам памяти. И если найдена копия первого байта, тогда переходим на следующий. И так пока не дойдете до конца. А файл надо сразу грузить в ОЗУ, если он не огроменный

Отредактировано balex1978 (27.08.2022 12:56:22)

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » поиск текста в памяти