gcue Posted April 1, 2009 Share Posted April 1, 2009 (edited) 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 April 1, 2009 by gcue Link to comment Share on other sites More sharing options...
Authenticity Posted April 1, 2009 Share Posted April 1, 2009 (edited) 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 April 1, 2009 by Authenticity Link to comment Share on other sites More sharing options...
gcue Posted April 1, 2009 Author Share Posted April 1, 2009 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 Link to comment Share on other sites More sharing options...
Authenticity Posted April 1, 2009 Share Posted April 1, 2009 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. Link to comment Share on other sites More sharing options...
Xenobiologist Posted April 1, 2009 Share Posted April 1, 2009 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 Link to comment Share on other sites More sharing options...
gcue Posted April 1, 2009 Author Share Posted April 1, 2009 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! Link to comment Share on other sites More sharing options...
gcue Posted April 1, 2009 Author Share Posted April 1, 2009 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. Link to comment Share on other sites More sharing options...
Xenobiologist Posted April 1, 2009 Share Posted April 1, 2009 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 Link to comment Share on other sites More sharing options...
Authenticity Posted April 1, 2009 Share Posted April 1, 2009 Very nice 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. Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted April 1, 2009 Moderators Share Posted April 1, 2009 If you're making the array to a string, may look at this: http://www.autoitscript.com/forum/index.ph...c=78776&hl= 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. Link to comment Share on other sites More sharing options...
Authenticity Posted April 1, 2009 Share Posted April 1, 2009 (edited) 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 it. ;] Edit: lol, quite complex function for this task, looks great. ;] Edited April 1, 2009 by Authenticity Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted April 1, 2009 Moderators Share Posted April 1, 2009 (edited) @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 April 1, 2009 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. Link to comment Share on other sites More sharing options...
gcue Posted April 2, 2009 Author Share Posted April 2, 2009 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 Link to comment Share on other sites More sharing options...
gcue Posted April 2, 2009 Author Share Posted April 2, 2009 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. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now