Jump to content
Sign in to follow this  
gcue

search utility

Recommended Posts

gcue

i have a txt file list of names which i have built into an array ($employees)

i want to create a gui that will allow users to search for names

sometimes folks have middle names that people dont know about..

so if someone searches for Michael Smith - Michael Anthony Smith won't come up.

im trying to figure out how to use regexp with this but am having difficulty, can anyone help?

here's what i have so far (get an error):

$folks = _ArrayToString($employees)
        
        $results = StringRegExp($folks, "(?i).*" & GUICtrlRead($query) & ".*"), 3)

        If Not @error Then
            MsgBox(0, "", $results)
        EndIf

thanks in advance

Edited by gcue

Share this post


Link to post
Share on other sites
Authenticity

You need to split the string on spaces. So Michael Anthony is [0]Michael, [1]Anthony and preform a simple loop:

For $i = 0 To UBound($aNames)-1
    For $j = 0 To UBound($aNameSplit)-1
       If Not StringRegExp($aNames[$i], '\b\Q' & $aNameSplit[$j] & '\E\b') Then ExitLoop
    Next

    If $j = UBound($aNameSplit)-1 Then ExitLoop
Next

Or something else...

Edited by Authenticity

Share this post


Link to post
Share on other sites
gcue

hmm do i just dim anamesplit? dont see where that variable came from.

also how do i didnt notice an output there.. how does it report search results?

thanks for ur help authenticity

Share this post


Link to post
Share on other sites
Authenticity

Maybe a little explanation is required ;]

$aNames is the array of names you have, i.e. [0]Anthony Michelle, [1]Maria JJ Copper, [2]Me Me

$aNameSplit is the name you search for but is split. Say you wanna search "Maria Copper" so it's split on space into:

$aNameSplit[0] = "Maria"

$aNameSplit[1] = "Copper"

If the inner loop ($j) is not equal to the split array upper bound then name could not be found on the current $aNames elements, which reminds me that the script need a fix:

.
.
.
For $j = 1 To $aNameSplit[0]
   ...
Next

If $j = $aNameSplit[0] Then ExitLoop ; You'll need to play also with $i to see if there was entire mismatch.

Share this post


Link to post
Share on other sites
Xenobiologist

Hi,

Dim $sRawText[5] = ['Michael Smith ','Michael Anthony Smith', 'Michael Anthony Mike Smith', 'Paul Simon', 'Boris Becker Smith']
$search = 'smith'
Dim $sPattern = $search

For $i = 0 To UBound($sRawText) - 1
    If  StringInStr($sRawText[$i], $sPattern, 0) <> 0  Then ConsoleWrite($sRawText[$i] & @CRLF)
Next

Mega


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
gcue

thanks for your help fellas..

xeno,

that works except if i search "boris smith" - "boris becker smith" doesnt coem up in the results..

thanks again!

Share this post


Link to post
Share on other sites
gcue

right but how does that anamesplit get created?

Maybe a little explanation is required ;]

$aNames is the array of names you have, i.e. [0]Anthony Michelle, [1]Maria JJ Copper, [2]Me Me

$aNameSplit is the name you search for but is split. Say you wanna search "Maria Copper" so it's split on space into:

$aNameSplit[0] = "Maria"

$aNameSplit[1] = "Copper"

If the inner loop ($j) is not equal to the split array upper bound then name could not be found on the current $aNames elements, which reminds me that the script need a fix:

.
.
.
For $j = 1 To $aNameSplit[0]
   ...
Next

If $j = $aNameSplit[0] Then ExitLoop ; You'll need to play also with $i to see if there was entire mismatch.

Share this post


Link to post
Share on other sites
Xenobiologist

Hi,

here is a short try

Global $sRawText[5] = ['Michael Smith ', 'Michael Anthony Smith', 'Michael Anthony Mike Smith', 'Paul Simon', 'Boris Becker Smith']
;~ Global $search = 'boris smith'
Global $search = 'smith'

_search($search, $sRawText)

Func _search($toFind, $search_A)
    Local $toFind_A = StringSplit($toFind, ' ', 2)
    If @error = 1 Then
        Local $toFind_A[1] = [$toFind]
    EndIf

    For $i = 0 To UBound($search_A) - 1
        For $y = 0 To UBound($toFind_A) - 1
            ConsoleWrite($toFind_A[$y] & " == " & $search_A[$i] & @CRLF)
            If StringInStr($search_A[$i], $toFind_A[$y] ) <> 0 Then
                If UBound($toFind_A) - 1 = $y Then
                    ConsoleWrite('! found : ' & $search_A[$i] & @CRLF)
                EndIf
            Else
                ExitLoop
            EndIf
        Next
    Next
EndFunc   ;==>_search

Mega


Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Share this post


Link to post
Share on other sites
Authenticity

Very nice :D

If there is a need to not match Michael when you use Mic or Johny with John then you can adopt using StringRegExp with word-boundary, otherwise StringInStr is sufficient.

Share this post


Link to post
Share on other sites
Authenticity

If you're making the array to a string, may look at this: http://www.autoitscript.com/forum/index.ph...c=78776&hl=

Func _VLookupAut($s_string, $s_find_column_value, $v_column, $v_offset, $f_partial_match = False, $f_escape_chars = True, $v_casesensitive = -1, $s_delim = ",")

If $v_casesensitive = -1 Or $v_casesensitive = Default Or Not $v_casesensitive Then

$v_casesensitive = "(?i)"

Else

$v_casesensitive = ""

EndIf

Local $s_partial_match = ""

If $f_partial_match Then $s_partial_match = ".*?"

If FileExists($s_string) Then $s_string = FileRead($s_string)

Local $a_split = StringSplit(StringStripCR($s_string), @LF)

Local $a_column, $i_start_row = 1, $i_column = 0, $i_offset = 0

; If an integer wasn't passed, then get the integer value of the column header name

If IsString($v_column) Or IsString($v_offset) Then

$a_column = StringRegExp($a_split[1], $v_casesensitive & "(?sad.gif""[." & $s_delim & "]+""|.*?))(?:\z|" & $s_delim & ")", 3)

EndIf

If IsString($v_column) Then

For $i = 0 To UBound($a_column) - 1

If $v_column = $a_column[$i] Then

$i_column = $i + 1

$i_start_row = 2

ExitLoop

EndIf

Next

If $i_column = 0 Then

If StringIsInt($v_column) = 0 Then Return SetError(1, 0, 0); No column specified or found

$i_column = Int($i_column)

EndIf

Else

$i_column = $v_column

EndIf

If IsString($v_offset) Then

For $i = 0 To UBound($a_column) - 1

If $v_offset = $a_column[$i] Then

$i_offset = $i + 1

ExitLoop

EndIf

Next

If $i_offset = 0 Then

If StringIsInt($v_offset) = 0 Then Return SetError(2, 0, 0); No column specified or found

$i_offset = Int($i_offset)

Else

$i_offset -= $i_column

EndIf

Else

$i_offset = $v_offset

EndIf

;Escape the escape chars

Local $s_pattern_escapechars = "(\.|\||\*|\?|\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)"

If $f_escape_chars Then

$s_find = StringRegExpReplace($s_find_column_value, $s_pattern_escapechars, "\\\1")

EndIf

$s_delim = StringRegExpReplace($s_delim, $s_pattern_escapechars, "\\\1")

;How many delimeters

Local $n_delimeters = UBound(StringRegExp($a_split[1], "(" & $s_delim & ")", 3))

If $n_delimeters = 0 Then Return SetError(3, 0, 0)

If $n_delimeters < ($i_offset - 1) Or $i_offset = 0 Or $i_offset = -$i_column Then Return SetError(4, 0, 0)

If $a_split[0] < $i_column Or $i_column = 0 Then Return SetError(5, 0, 0)

Local $n_total_count = $i_column + $i_offset

Local $n_ubound = $n_total_count

If $i_offset < 0 Then $n_ubound = $i_column

; Prepare the regex pattern

Local $s_pattern_findvalue = $v_casesensitive, $i

For $i = 1 To $n_ubound

If $i_column = $i Then

If $i_offset < 0 Then

If $n_total_count = $i Then

$s_pattern_findvalue &= "(.*?)" & $s_delim & $s_partial_match & $s_find & $s_partial_match

Else

$s_pattern_findvalue &= $s_partial_match & $s_find & $s_partial_match

EndIf

Else

$s_pattern_findvalue &= $s_partial_match & $s_find & $s_partial_match & $s_delim

EndIf

ElseIf $n_total_count = $i Then

If $i_offset < 0 Then

$s_pattern_findvalue &= "(.*?)" & $s_delim

Else

$s_pattern_findvalue &= "(.*?)"

EndIf

Else

$s_pattern_findvalue &= "(?:""[." & $s_delim & "]+""|.*?)" & $s_delim

EndIf

Next

$s_pattern_findvalue &= "(?:\z|" & $s_delim & ")"

; Could be done with 1 line of regex, but [0] wouldn't hold the array ubound value.

; Also, splitting it up since we already did stringsplit, will prove to be pretty fast anyway without a large string to search

Local $a_match[$a_split[0] + 1], $i_add, $a_sre

For $i = $i_start_row To $a_split[0]

$a_sre = StringRegExp($a_split[$i], $s_pattern_findvalue, 1)

If IsArray($a_sre) Then

$i_add += 1

$a_match[$i_add] = $a_sre[0]

EndIf

Next

If Not $i_add Then Return SetError(6, 0, 0)

ReDim $a_match[$i_add + 1]

$a_match[0] = $i_add

SetExtended($i_add)

Return $a_match

I think you may want to de :D it. ;]

Edit: lol, quite complex function for this task, looks great. ;]

Edited by Authenticity

Share this post


Link to post
Share on other sites
SmOke_N

@Authenticity, not sure what you're asking there. I should probably have turned emoticons off if I didn't if that's what you're saying.

@OP, I'm not sure RegEx is needed here at all (can't believe I'm saying that), using Mega's (oops, Xeno's) array, Split+StringInStr() should do the trick:

#include <array.au3>
Global $sRawText[5] = ['Michael Smith ', 'Michael Anthony Smith', 'Michael Anthony Mike Smith', 'Paul Simon', 'Boris Becker Smith']

Global $a_search = _Employee_Lookup($sRawText, "boris smith")
_ArrayDisplay($a_search)

Func _Employee_Lookup($a_list, $s_find_name, $i_start = 0, $i_end = 0)
    
    If $i_end = 0 Then $i_end = UBound($a_list) - 1
    If $i_end < $i_start Then Return SetError(1, 0, 0)
    
    Local $a_split = StringSplit(StringStripWS($s_find_name, 7), " ")
    If $a_split[0] > 3 Then Return SetError(2, 0, 0)
    
    Local $a_ret[$i_end + 1], $i_found = 0, $i_add = 0
    
    For $i = $i_start To $i_end
        $i_found = 0
        For $j = 1 To $a_split[0]
            If StringInStr($a_list[$i], $a_split[$j]) Then $i_found += 1
        Next
        If $i_found = $a_split[0] Then
            $a_ret[$i_add] = $a_list[$i]
            $i_add += 1
        EndIf
    Next
    
    If $i_add = 0 Then Return SetError(3, 0, 0)
    
    ReDim $a_ret[$i_add]
    Return $a_ret
EndFunc

Edit:

Had two SetError(1, 0, 0)'s .

Edit2:

In VLookUp, I had emoticons turned off. Not sure why you have sad.gif.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
gcue

thanks xeno!

works great!

Hi,

here is a short try

Global $sRawText[5] = ['Michael Smith ', 'Michael Anthony Smith', 'Michael Anthony Mike Smith', 'Paul Simon', 'Boris Becker Smith']
;~ Global $search = 'boris smith'
Global $search = 'smith'

_search($search, $sRawText)

Func _search($toFind, $search_A)
    Local $toFind_A = StringSplit($toFind, ' ', 2)
    If @error = 1 Then
        Local $toFind_A[1] = [$toFind]
    EndIf

    For $i = 0 To UBound($search_A) - 1
        For $y = 0 To UBound($toFind_A) - 1
            ConsoleWrite($toFind_A[$y] & " == " & $search_A[$i] & @CRLF)
            If StringInStr($search_A[$i], $toFind_A[$y] ) <> 0 Then
                If UBound($toFind_A) - 1 = $y Then
                    ConsoleWrite('! found : ' & $search_A[$i] & @CRLF)
                EndIf
            Else
                ExitLoop
            EndIf
        Next
    Next
EndFunc   ;==>_search

Mega

Share this post


Link to post
Share on other sites
gcue

works great smoke!

thanks man

@Authenticity, not sure what you're asking there. I should probably have turned emoticons off if I didn't if that's what you're saying.

@OP, I'm not sure RegEx is needed here at all (can't believe I'm saying that), using Mega's (oops, Xeno's) array, Split+StringInStr() should do the trick:

#include <array.au3>
Global $sRawText[5] = ['Michael Smith ', 'Michael Anthony Smith', 'Michael Anthony Mike Smith', 'Paul Simon', 'Boris Becker Smith']

Global $a_search = _Employee_Lookup($sRawText, "boris smith")
_ArrayDisplay($a_search)

Func _Employee_Lookup($a_list, $s_find_name, $i_start = 0, $i_end = 0)
    
    If $i_end = 0 Then $i_end = UBound($a_list) - 1
    If $i_end < $i_start Then Return SetError(1, 0, 0)
    
    Local $a_split = StringSplit(StringStripWS($s_find_name, 7), " ")
    If $a_split[0] > 3 Then Return SetError(2, 0, 0)
    
    Local $a_ret[$i_end + 1], $i_found = 0, $i_add = 0
    
    For $i = $i_start To $i_end
        $i_found = 0
        For $j = 1 To $a_split[0]
            If StringInStr($a_list[$i], $a_split[$j]) Then $i_found += 1
        Next
        If $i_found = $a_split[0] Then
            $a_ret[$i_add] = $a_list[$i]
            $i_add += 1
        EndIf
    Next
    
    If $i_add = 0 Then Return SetError(3, 0, 0)
    
    ReDim $a_ret[$i_add]
    Return $a_ret
EndFunc

Edit:

Had two SetError(1, 0, 0)'s .

Edit2:

In VLookUp, I had emoticons turned off. Not sure why you have sad.gif.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.