From: Richard Mueller [MVP] on 1 May 2010 15:14 "Check" <guest(a)unknown-email.com> wrote in message news:4624676b524437ec0fa8a6e01b1ad9e6(a)nntp-gateway.com... > > I have written something like this: > > Dim sStringToSearch() > ReDim sStringToSearch(1) > > sStringToSearch(0) = "ame i" > sStringToSearch(1) = "ti" > > bCaseSensitive = False > For Each sValue In sStringToSearch > If bCaseSensitive <> True Then > sValue = LCase(sValue) > End If > > sLogFilePath = "C:\Test\Test.txt" > Set objFSO = CreateObject("Scripting.FileSystemObject") > strData = objFSO.OpenTextFile(sLogFilePath & sFileName, 1).ReadAll > > arrLines = Split(strData, vbCrLf) > > For iLineCount = 0 To UBound(arrLines) > iOccur = 0 > sString = "" > sLineData = arrLines(iLineCount) > If bCaseSensitive = False Then > sLineData = LCase(sLineData) > End If > > For iCount = 1 To Len(sLineData) > If InStr(iCount, sLineData, sValue) > 0 Then > iLocationOfString = InStr(iCount, sLineData, sValue) > iTrailingSpace = InStrRev(sLineData, " ", > iLocationOfString) > If iTrailingSpace = 0 Then > iTrailingSpace = 0 > End If > iLeadingSpace = InStr(iLocationOfString + Len(sValue), > sLineData, " ") > If iLeadingSpace = 0 Then > iLeadingSpace = Len(sLineData) + 1 > End If > iWordLength = iLeadingSpace - iTrailingSpace - 1 > > sWord = Mid(sLineData, iTrailingSpace + 1, iWordLength) > Else > Exit For > End If > sString = sString & "|" & sWord > iCount = iLeadingSpace > iOccur = iOccur + 1 > Next > If iOccur > 0 Then > MsgBox "String To Search: " & sValue > MsgBox "Line Number: " & iLineCount + 1 > MsgBox "Occurance: " & iOccur > MsgBox "Matching words found: " & sString > End If > Next > Next > > This caters everything - string search, list of string search, case > sensitive search. > > Is there any better way to implement this? > > Also, can anyone tell me how to implement wild card search in VBScript? > > Example: sGivenString = "My name is Peter. Her name is Latika" > > sStringToSearch = "n*e" > > Result should be: occurrence = 2, name > > if string to search = P?t > occurrence = 1, Peter > > > -- > Check I have an example VBScript program that uses the RegEx object. I use it to analyze regular expression patterns. I documented the program with many comments to explain how to use regular expressions. As noted, it is based on a program in Tim Hill's "Windows 2000 Windows Script Host". I used it to handle your examples with the following commands (the program is called RegExpMatch.vbs): cscript //nologo RegExpMatch.vbs "n[A-Za-z]+e" "My name is Peter. Her name is Latika" the output was: Pattern: "n[A-Za-z]+e" String: "My name is Peter. Her name is Latika" Number of matches: 2 Match: name at: 4 (4) Match: name at: 23 (4) Next I used the command: cscript //nologo RegExpMatch.vbs "P[A-Za-z]t" "My name is Peter. Her name is Latika" and the output was: Pattern: "P[A-Za-z]t" String: "My name is Peter. Her name is Latika" Number of matches: 1 Match: Pet at: 12 (3) The program follows: ============ ' RegExpMatch.vbs ' Version 1.0 ' January 8, 2010 ' VBScript program to test various regular expression patterns ' and their affect on strings. ' Based on script RegExp.vbs (Listing 7.1 on page 197) from ' "Windows 2000 Windows Script Host" by Tim Hill, ' Macmillan Technical Publishing, Copyright 1999. ' Examples of patterns: ' . any character ' .. any 2 characters ' ^abc string starts wtih abc ' red$ string ends with red ' [0-9] a digit ' [0-9]* 0 or more digits ' [0-9]+ 1 or more digits ' [0-9]? 0 or 1 digit ' [0-9a-zA-Z] alphanumeric character ' [^0-9] not a digit ' [a-zA-Z][a-zA-Z_0-9]* valid variable name ' a{3} aaa ' a{3,} at least three a characters ' a{3,5} 3 to 5 a's ' [0-9]{4} 4 digits ' \d any digit, same as [0-9] ' \D any non-digit, same as [^0-9] ' \w any word character, same as [0-9a-zA-Z_] ' \W any non-word character ' \b word boundary ' \B non-word boundary ' \s whitespace character ' \S non-whitespace character ' \f form-feed character ' \n new-line character ' \r carriage-return character ' \v vertical tab character ' \onn octal code nn ' \xnn hexadecimal code nn ' \n (n a digit) repeat previous sub expression (in parentheses) n times ' (..)\1 any two characters repeated twice, like abab ' ab|ac ab or ac ' ^ab|ac$ ab at start or ac at end of string ' ^(ab|ac)$ either string ab or ac ' [^=]+=.* command line arguments ' ([a-zA-Z]\w*)=(.*) command line arguments ' (\s*)([a-zA-Z]\w*)(\s*)=(.*) command line arguments, with whitespace ' (\s*)/([a-zA-Z]\w*)((=|:)(.*)|) command line switch ' ^(.*?)\1+$ any repeating pattern in a string Option Explicit Dim objRE, objMatches, objMatch, strPattern, strSearchString Select Case Wscript.Arguments.Count Case 1 strPattern = Wscript.Arguments(0) If (strPattern = "/?") _ Or (strPattern = "-?") _ Or (strPattern = "?") _ Or (strPattern = "/H") _ Or (strPattern = "/h") _ Or (strPattern = "-H") _ Or (strPattern = "-h") _ Or (strPattern = "/help") _ Or (strPattern = "-help") Then Call Syntax() Wscript.Quit End If Case 2 strPattern = Wscript.Arguments(0) strSearchString = Wscript.Arguments(1) Case Else Wscript.Echo "Wrong number of arguments" Call Syntax() Wscript.Quit End Select Wscript.Echo "Pattern: """ & strPattern & """" Wscript.Echo "String: """ & strSearchString & """" Set objRE = New RegExp objRE.Pattern = strPattern objRE.Global = True Set objMatches = objRE.Execute(strSearchString) Wscript.Echo "Number of matches: " & objMatches.Count For Each objMatch In objMatches Wscript.Echo "Match: " & objMatch.Value & " at: " _ & CStr(objMatch.FirstIndex + 1) & " (" & objMatch.Length & ")" Next Sub Syntax() Wscript.Echo "Syntax:" Wscript.Echo " cscript RegExpMatch.vbs <pattern> <string>" Wscript.Echo "where:" Wscript.Echo " <pattern> is a regular expression pattern" Wscript.Echo " <string> is a string to test against the pattern" Wscript.Echo "For example:" Wscript.Echo " cscript RegExpMatch.vbs ""[A-Za-z0-9\+/]+[=]?[=]?"" ""VGhpcyBpcyBhIHRlc3Q=""" End Sub -- Richard Mueller MVP Directory Services Hilltop Lab - http://www.rlmueller.net --
From: Pegasus [MVP] on 1 May 2010 15:49
"Check" <guest(a)unknown-email.com> wrote in message news:4624676b524437ec0fa8a6e01b1ad9e6(a)nntp-gateway.com... > > I have written something like this: > > Dim sStringToSearch() > ReDim sStringToSearch(1) > > sStringToSearch(0) = "ame i" > sStringToSearch(1) = "ti" > > bCaseSensitive = False > For Each sValue In sStringToSearch > If bCaseSensitive <> True Then > sValue = LCase(sValue) > End If > > sLogFilePath = "C:\Test\Test.txt" > Set objFSO = CreateObject("Scripting.FileSystemObject") > strData = objFSO.OpenTextFile(sLogFilePath & sFileName, 1).ReadAll > > arrLines = Split(strData, vbCrLf) > > For iLineCount = 0 To UBound(arrLines) > iOccur = 0 > sString = "" > sLineData = arrLines(iLineCount) > If bCaseSensitive = False Then > sLineData = LCase(sLineData) > End If > > For iCount = 1 To Len(sLineData) > If InStr(iCount, sLineData, sValue) > 0 Then > iLocationOfString = InStr(iCount, sLineData, sValue) > iTrailingSpace = InStrRev(sLineData, " ", > iLocationOfString) > If iTrailingSpace = 0 Then > iTrailingSpace = 0 > End If > iLeadingSpace = InStr(iLocationOfString + Len(sValue), > sLineData, " ") > If iLeadingSpace = 0 Then > iLeadingSpace = Len(sLineData) + 1 > End If > iWordLength = iLeadingSpace - iTrailingSpace - 1 > > sWord = Mid(sLineData, iTrailingSpace + 1, iWordLength) > Else > Exit For > End If > sString = sString & "|" & sWord > iCount = iLeadingSpace > iOccur = iOccur + 1 > Next > If iOccur > 0 Then > MsgBox "String To Search: " & sValue > MsgBox "Line Number: " & iLineCount + 1 > MsgBox "Occurance: " & iOccur > MsgBox "Matching words found: " & sString > End If > Next > Next > > This caters everything - string search, list of string search, case > sensitive search. > > Is there any better way to implement this? > > Also, can anyone tell me how to implement wild card search in VBScript? > > Example: sGivenString = "My name is Peter. Her name is Latika" > > sStringToSearch = "n*e" > > Result should be: occurrence = 2, name > > if string to search = P?t > occurrence = 1, Peter > > > -- > Check I did not check the logic of your program in detail but here are some general comments: [01] Dim aStringToSearch(1) [02] 'ReDim sStringToSearch(1) [03] sLogFilePath = "C:\Test\Test.txt" [04] Set objFSO = CreateObject("Scripting.FileSystemObject") [05] [06] aStringToSearch(0) = "ame i" [07] aStringToSearch(1) = "ti" [08] [09] bCaseSensitive = False [10] For Each sValue In aStringToSearch [11] If not bCaseSensitive Then sValue = LCase(sValue) [12] strData = objFSO.OpenTextFile(sLogFilePath & sFileName, 1).ReadAll [13] arrLines = Split(strData, VbCrLf) [14] [15] For iLineCount = 0 To UBound(arrLines) [16] iOccur = 0 [17] sString = "" [18] sLineData = arrLines(iLineCount) [19] If not bCaseSensitive Then sLineData = LCase(sLineData) [20] [21] For iCount = 1 To Len(sLineData) [22] If InStr(iCount, sLineData, sValue) > 0 Then [23] iLocationOfString = InStr(iCount, sLineData, sValue) [24] iTrailingSpace = InStrRev(sLineData, " ", iLocationOfString) [25] ' If iTrailingSpace = 0 Then iTrailingSpace = 0 [26] iLeadingSpace = InStr(iLocationOfString + Len(sValue),sLineData, " ") [27] If iLeadingSpace = 0 Then iLeadingSpace = Len(sLineData) + 1 [28] iWordLength = iLeadingSpace - iTrailingSpace - 1 [29] sWord = Mid(sLineData, iTrailingSpace + 1, iWordLength) [30] Else [31] Exit For [32] End If [33] sString = sString & "|" & sWord [34] iCount = iLeadingSpace [35] iOccur = iOccur + 1 [36] Next [37] If iOccur > 0 Then MsgBox "String To Search: " & sValue & vbLf & _ [38] "Line Number: " & iLineCount + 1 & vbLf & _ [39] "Occurance: " & iOccur & vbLf & _ [40] "Matching words found: " & sString [41] Next [42] Next General: By not indenting your code, you destroy its structure and make life difficult for yourself. This is particularly true when you have nested loops. Line 01: While you are at liberty to assign any name to your variables, prefixing an array with "s" (=string) is misleading and will cause maintenance problems. Line 02: This line is superfluous. Delete it. Line 03: Having a "constant" statement (which this really is) inside a loop is wasting processor time. Put it right at the beginning of your code. Line 04: Recreating the same object inside a loop is wasting processor time. Put it right at the beginning of your code. Line 11: Your code If bCaseSensitive = False Then sLineData = LCase(sLineData) End If can be rewritten more elegantly as "If not bCaseSensitive Then sValue = LCase(sValue)" Line 12: sFileName is an undeclared variable. Line 25: This code does nothing useful. Get rid of it. Lines 37-40: Your original code generates multiple message boxes. Do you really want them? About your wildcard searches: See Richard Mueller's response. It is good programming practice to close your open files when finished with them. To do this you should replace this line: [12] strData = objFSO.OpenTextFile(sLogFilePath & sFileName, 1).ReadAll with these lines: [12] Set oFile = objFSO.OpenTextFile(sLogFilePath & sFileName) [13] strData = oFile.ReadAll [14] oFile.Close |