flat assembler
Message board for the users of flat assembler.
Index
> Windows > [String algorithm]How to do string wildcard search/replaces? |
Author |
|
Vasilev Vjacheslav 23 Jul 2006, 07:34
strange, but i also working on this problem and yesterday i wrote such algorithm of course author right belongs to me
Code: szFind db "DEST_STRING" szFindMask db 0,1,0,0,0,0,0,0,0,0,0 ; 1 - skip searching byte szReplace db "ABCD_EFGHJK" szReplaceMask db 0,1,1,1,1,1,1,1,1,1,0 ; 1 - skip writing byte hPatSize dd 11 ; backward byte pattern search/replace algorithm by mask proc _snr uses ebx esi edi, lpMem,hMemSize,lpFind,lpFindMask,lpReplace,lpReplaceMask,hPatSize locals hRetValue dd ? endl mov ebx,[lpMem] mov ecx,[hMemSize] mov edi,[hFindSize] and [hRetValue],0 or ecx,ecx jz .ret or edi,edi jz .ret .again: mov al,byte [ebx+ecx-1] mov edx,[hFindStr] cmp al,byte [edx+edi-1] jnz .next lea edx,[edi-1] lea eax,[ecx-1] cmp edx,eax ja .ret .search_loop: mov al,byte [ebx+ecx-2] mov esi,[hFindStr] dec ecx cmp al,byte [esi+edx-1] jz @F mov eax,[hFindStrMsk] cmp byte [edx+eax-1],0 jz .next_test @@: dec edx jnz .search_loop lea eax,[ebx+ecx-1] mov edx,edi lea esi,[eax+edi-1] .replace_loop: mov eax,[hReplaceStrMsk] cmp byte [eax+edx-1],0 jnz @F mov eax,[hReplaceStr] mov al,byte [edx+eax-1] inc [hRetValue] mov byte [esi],al @@: dec esi dec edx jnz .replace_loop cmp edi,ecx ja .ret .next: dec ecx .next_test: or ecx,ecx jnz .again .ret: mov eax,[hRetValue] ret endp ps. fixed length searching and tested not much |
|||
23 Jul 2006, 07:34 |
|
kohlrak 23 Jul 2006, 14:18
What's needed the most (that most wildcard check systems don't have) is for the wild card to be only restricted by spaces when checking for the search word... for example:
context F##udge Searcher *udge and still find the word in the context. Also to be able to tell when it's not at the end of the searched for word (so we could say "F*e" and still find teh word in the context). But i have a feeling i'm gonna end up makin' that code and have to look at all yours for a base. (and no, incase you're worried since i'm new, i really do mean look, not copy and paste. lol) |
|||
23 Jul 2006, 14:18 |
|
f0dder 23 Jul 2006, 14:31
PCRE
|
|||
23 Jul 2006, 14:31 |
|
kohlrak 23 Jul 2006, 15:25
PCRE?
|
|||
23 Jul 2006, 15:25 |
|
f0dder 23 Jul 2006, 19:15
|
|||
23 Jul 2006, 19:15 |
|
kohlrak 23 Jul 2006, 19:28
oh cool, so we already have it, we just need to open up an exe in perle and locate it and change the code so it works better. lol
|
|||
23 Jul 2006, 19:28 |
|
f0dder 23 Jul 2006, 19:33
You didn't look very closely, did you?
It's a C library that provides perl compatible regular expressions. Since it's in C, it's linkable from just about everything. If you need the power of regular expressions (ie, more than just '?' and '*'), it's hard to find anything much better than this. |
|||
23 Jul 2006, 19:33 |
|
kohlrak 23 Jul 2006, 19:59
Fine, we'll open it up. lol
|
|||
23 Jul 2006, 19:59 |
|
f0dder 23 Jul 2006, 20:04
It's overkill if you only need '?' and '*' though. But if you want full regular expression support, it's more sane to use PCRE than starting your own - it's a massive task to get regex working, stable and efficient.
|
|||
23 Jul 2006, 20:04 |
|
kohlrak 23 Jul 2006, 20:19
the simple idea is to take what i want out the teh DLL or whatever (and then cutting out the junk of that and rewriting some of the loops more efficiantly and such.
|
|||
23 Jul 2006, 20:19 |
|
ronware 25 Jul 2006, 17:58
PCRE is an excellent and quite efficient library. I doubt "rewriting some of the loops" will be a simple excersize or worth the time you spend on it.
|
|||
25 Jul 2006, 17:58 |
|
kohlrak 25 Jul 2006, 18:45
Eh, maybe, maybe not... I'm thinking about working on a new project some day where i'll build a little digital assistant like thing with instant message capabilities. I won't go into all the details, but it won't require people to pay for some wireless service...
|
|||
25 Jul 2006, 18:45 |
|
f0dder 26 Jul 2006, 08:06
kohlrak wrote: Eh, maybe, maybe not... I'm thinking about working on a new project some day where i'll build a little digital assistant like thing with instant message capabilities. I won't go into all the details, but it won't require people to pay for some wireless service... What does that have to do with this thread? _________________ - carpe noctem |
|||
26 Jul 2006, 08:06 |
|
kohlrak 26 Jul 2006, 08:15
Well.... Directly to the post itself... nothing... lol But it points out that editing and using the smallest code possible would be required, even if it seems unimportant.
|
|||
26 Jul 2006, 08:15 |
|
wht36 15 Nov 2008, 06:49
I've found a wildcard matching routine by comrade ( http://comrade.ownz.com/ ) and made some changes to so it doesn't look like his original routine anymore, but the idea was his.
The wmatch routine is the actual routine. I've included some stuff in front so one can assemble and test it. Code: org 100h mov si,mask mov di,string call wmatch add al,'0' int 29h ret mask: db "*",0 string: db "Hello",0 ;Compare nul terminated SI mask to DI string ;Return AX non-zero if match wmatch: .new: xor cx, cx ; clear wildcard indicator .chkz: sub ax, ax ; initialize return value cmp al, [si] ; check for end of mask jne .next cmp byte [di], 1 ; return TRUE if end of source adc ax, cx ; OR if end of mask is wildcard ret .cmp3: inc di ; else if no match cmp [di], ah jz .error .next: mov al, [si] cmp al, "*" je .wild ; if * then set wildcard indicator to TRUE jcxz .nowc ; if not wildcard indicator then match char sub bx,bx ; Wildcard loop - initialize base counter .cmp2: test ax, ax ; if no more char in mask then end current match jz .mtch cmp al, "?" ; if ? then skip one char je .sc cmp al, [bx+di] jne .cmp3 .sc: inc bx ; Increment base counter if match mov al, [bx+si] ; cmp al, "*" ; If next byte in mask is * then end current match jne .cmp2 .mtch: inc di inc si ; move to next byte in source & mask jmp .new .wild: inc cx ; set wildcard indicator to TRUE inc si ; move to next byte in mask jmp .chkz ; check for end of mask & end of source .nowc: cmp al, "?" ; if ? then je .mtch ; match next char cmp al, [di] ; else if char matches je .mtch .error: xor ax, ax ; or return FALSE ret |
|||
15 Nov 2008, 06:49 |
|
comrade 27 Feb 2009, 14:42
It is amazing you were able to understand what it does, and actually rename the labels and add comments. I wrote this many years ago when I did neither, and looking at it now, I have no idea what it does... this day I would use PCRE though. It even has JIT-like support for performance
|
|||
27 Feb 2009, 14:42 |
|
wht36 21 Mar 2009, 10:53
PCRE is very powerful but I like your code very much. For simple jobs I think it is very lovely indeed. Thanks again for providing the code!
|
|||
21 Mar 2009, 10:53 |
|
booter 29 Apr 2009, 06:51
It's a bit off-topic, but a while ago I wrote a function that looks for a substring in a string (case insensitive). It's rather easy (though less effective) to implement wildcard search based on searching for substrings. Anyway, below is my code, not optimal, though.
Code: macro Return rc {mov dword [esp+28],rc} ; inside pushad/popad proc Pos strptr:DWORD,search:DWORD pushad mov eax,[strptr] mov edi,[search] dec eax .tst: ; iterate source inc eax mov edx,edi ; edx->search .tst2: ; iterate search mov cl,byte [edx] cmp cl,0 je .found ; end of search str mov ch,byte [eax] cmp ch,0 ; if we got here - end of source je .fail cmp ch,cl je .same ; case insensitivity jnc .nx ; ch < cl xchg cl,ch .nx: ; now ch > cl, meaning only cl may be lower case add cl,20h ; to upper case cmp cl,ch jne .tst ; different cmp cl,61h ; 'A' jc .tst ; out of range cmp cl,7Bh ; 'Z'+1 jnc .tst ; out of range .same: inc edx ; next in search inc eax ; next in source jmp .tst2 .fail: Return 0 popad ret .found: sub eax,[strptr] ; current offset add eax,edi sub eax,edx ; - search len inc eax ; offset to Pos Return eax popad ret endp |
|||
29 Apr 2009, 06:51 |
|
Madis731 29 Apr 2009, 07:52
|
|||
29 Apr 2009, 07:52 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.