Need to capture patterns and replace code in file VBScripts - regex

The code in file abc is which needs to captured with Regex.
With TeWindow("tewindow").Tescreen("something").TeField("some")
.set "value"
.setToProperty "V"
.exist(0)
End With
This code should be replaced in abc with
'With TeWindow("tewindow").Tescreen("something").TeField("some")
myset("something_some"), "value"
mysetToProperty("something_some"), ""
myExist("something_some"), (0)
'End With
Following is the trial so far. I'm not able to make it to writing in the file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set testfile = objFSO.OpenTextFile("D:\test\testout4.txt", 1, True)
line = testfile.ReadAll
testfile.Close
sString = line
pat = "with[\s]{1,}tewindow\((.*?)\).tescreen\((.*?)\).tefield\((.*?)\)" '12
pat1 = "^\.[a-zA-Z]{1,}"
Call DeclareRegEx(objRE,pat)
If objRE.test(sString) Then
Set Matches = objRE.Execute(sString)
Set match = Matches(0)
intcount = match.SubMatches.Count
If intcount > 0 Then
For I = 1 To intcount-1
'If i = intcount-1 Then
objRef = objRef & match.SubMatches(I)
Next
Else '30
objRef = objRef & match.SubMatches(I) & "_"
End If
End If
call DeclareRegEx(objRE1, pat1)
If objRE1.Test(sString) Then
Set Matches1 = objRE1.Execute(sString)
For Each Match1 in Matches1
RetStr1 = Match1.Value
strplc = Right(RetStr1, Len(RetStr1) - 1)
actual = objRE1.Replace(RetStr1, "my" & strplc & "(" & objRef & ")")
MsgBox actual
Next
End If
Function DeclareRegEx(obj, pattern)
Set obj = New RegExp
obj.Global = True
obj.Multiline = True
obj.Pattern = pattern
obj.IgnoreCase = True
End Function
Suggestion for some other approach or regex is welcome.

well as the approach of finding the block , being captured by verbose regex is not seemed to be a generic in the code i tried something like the following..
take the file content into an array
2.find the line no of with and end with
3.run a loop to iterate the functions from the next line of the with till line before the end with.
it worked for me !

Related

Find '~XX~' within a string with specific values

I have classic ASP written in VBScript. I have a record pulled from SQL Server and the data is a string. In this string, I need to find text enclosed in ~12345~ and I need to replace with very specific text. Example 1 would be replaced with M, 2 would be replaced with A. I then need to display this on the web page. We don't know how many items will be enclosed with ~.
Example Data:
Group Pref: (To be paid through WIT)
~2.5~ % Quarterly Rebate - Standard Commercial Water Heaters
Display on webpage after:
Group Pref: (To be paid through WIT)
~A.H~ % Quarterly Rebate - Standard Commercial Water Heaters
I tried this following, but there are two many cases and this would be unrealistic to maintain. I does replace the text and display correctly.
dim strSearchThis
strSearchThis =(rsResults("PREF"))
set re = New RegExp
with re
.global = true
.pattern = "~[^>]*~"
strSearchThis = .replace(strSearchThis, "X")
end with
I am also trying this code, I can find the text contained between each ~ ~, but when displayed its the information between the ~ ~ is not changed:
dim strSearchThis
strSearchThis =(rsResults("PREF"))
Set FolioPrefData = New RegExp
FolioPrefData.Pattern = "~[^>]*~"
FolioPrefData.Global = True
FolioPrefData.IgnoreCase = True
'will contain all found instances of ~ ~'
set colmatches = FolioPrefData.Execute(strSearchThis)
Dim itemLength, found
For Each objMatch in colMatches
Select Case found
Case "~"
'ignore - doing nothing'
Case "1"
found = replace(strSearchThis, "M")
End Select
Next
response.write(strSearchThis)
You can do it without using Regular Expressions, just checking the individual characters and writing a function that handles the different cases you have. The following function finds your delimited text and loops through all characters, calling the ReplaceCharacter function defined further down:
Function FixString(p_sSearchString) As String
Dim iStartIndex
Dim iEndIndex
Dim iIndex
Dim sReplaceString
Dim sReturnString
sReturnString = p_sSearchString
' Locate start ~
iStartIndex = InStr(sReturnString, "~")
Do While iStartIndex > 0
' Look for end ~
iEndIndex = InStr(iStartIndex + 1, sReturnString, "~")
If iEndIndex > 0 Then
sReplaceString = ""
' Loop htrough all charatcers
For iIndex = iStartIndex + 1 To iEndIndex - 1
sReplaceString = sReplaceString & ReplaceCharacter(Mid(sReturnString, iIndex, 1))
Next
' Replace string
sReturnString = Left(sReturnString, iStartIndex) & sReplaceString & Mid(sReturnString, iEndIndex)
' Locate next ~
iStartIndex = InStr(iEndIndex + 1, sReturnString, "~")
Else
' End couldn't be found, exit
Exit Do
End If
Loop
FixString = sReturnString
End Function
This is the function where you will enter the different character substitutions you might have:
Function ReplaceCharacter(p_sCharacter) As String
Select Case p_sCharacter
Case "1"
ReplaceCharacter = "M"
Case "2"
ReplaceCharacter = "A"
Case Else
ReplaceCharacter = p_sCharacter
End Select
End Function
You can use this in your existing code:
response.write(FixString(strSearchThis))
You can also use a Split and Join method...
Const SEPARATOR = "~"
Dim deconstructString, myOutputString
Dim arrayPointer
deconstructString = Split(myInputString, SEPARATOR)
For arrayPointer = 0 To UBound(deconstructString)
If IsNumeric(deconstructString(arrayPointer)) Then
'Do whatever you need to with your value...
End If
Next 'arrayPointer
myOutputString = Join(deconstructString, "")
This does rely, obviously, on breaking a string apart and rejoining it, so there is a sleight overhead on string mutability issues.

Clean blanks/whitespace to vbNull with RegEx

I am looking to clean up a .csv file for a database import. I am using the following vbs function and would like to incorporate '' to vbNull. I find it hard to understand RegEx. Can this even be done?
Function removeEmbeddedCommasInCSVTextField (strtoclean)
Dim objRegExp, outputStr
Set objRegExp = New Regexp
objRegExp.IgnoreCase = True
objRegExp.Global = True
objRegExp.Pattern = """[^""]*,[^""]*"""
Set objMatch = objRegExp.Execute( strtoclean )
corrected_row = strtoclean
For Each myMatch in objMatch
matched_value = myMatch.Value ' retrieves text column with embedded commas
cleaned_value = replace(matched_value, ",","") ' removes embeddes commans from column
corrected_row = replace(corrected_row, matched_value, cleaned_value) 'take row and replaced bad value with good value (no commas)
Next
removeEmbeddedCommasInCSVTextField = corrected_row
End Function
MAIN:
Set MyFile = fso.CreateTextFile(strShareDirectory & "fixed.txt", True)
Set f = fso.OpenTextFile(strShareDirectory & filename)
Do Until f.AtEndOfStream
before_clean = f.ReadLine
after_clean = removeEmbeddedCommasInCSVTextField(before_clean)
MyFile.WriteLine(after_clean)
'WScript.Echo after_clean
Loop
f.Close
MyFile.Close

RegExp numbers between single quotes

I have a string like this "f_details('277095');">. I just need to get the 277095 part. I've been trying variations of strPattern = "'[0-9]'+", but this is either finding nothing or finding the wrong things.
I don't understand regular expressions despite having a cheat sheet right in front of me. Spent an hour trying different things already. What would this regexp look like?
Here is my code that I use to scrape this site and grab data:
Set objWshShell = Wscript.CreateObject("Wscript.Shell")
Set IE = CreateObject("internetexplorer.application")
Set fso = CreateObject("Scripting.FileSystemObject")
on error resume next
For i=1 To 77 '77 Counties
If i=77 Then Exit For
IE.Visible = True
IE.Navigate "https://lic.ok.gov/PublicPortal/OREC/FindAssociateEntity.jsp"
Do Until IE.ReadyState = 4: WScript.sleep 15: Loop
Do Until IE.Document.ReadyState = "complete": WScript.sleep 10: Loop
IE.Document.getElementsByTagName("select")("AddrCountyCode").Value = i
Do Until IE.Document.ReadyState = "complete": WScript.sleep 10: Loop
For Each btn In IE.Document.getElementsByTagName("input")
If btn.name = "btnSearch" Then btn.Click()
NEXT
strPattern = "'(\d+)'"
strTestString = ie.document.body.innerhtml
arrAllMatches = fGetMatches(strPattern, strTestString)
If UBound(arrAllMatches) <> 0 Then
filename = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) & "\License.txt"
set fso = createobject("scripting.filesystemobject")
set ts = fso.opentextfile(filename,8,true)
ts.write Join(arrAllMatches, vbCrlf)
ts.close
Else
WScript.Echo "-- None Found --"
End if
next
Wscript.echo "DONE!"
'=====================================================================
Function fGetMatches(sPattern, sStr)
Dim regEx, retVal, sMatch, colMatches, temp
Set regEx = New RegExp ' Create a regular expression.
regEx.Pattern = sPattern ' Set pattern.
regEx.IgnoreCase = True ' Set case insensitivity.
regEx.Global = True ' Set global applicability.
Set colMatches = regEx.Execute(sStr) ' Execute search.
If colMatches.Count = 0 Then
temp = Array("")
Else
'# Convert Collection to Array
For Each sMatch In colMatches
temp = temp & sMatch & "¶"
Next
temp = Left(temp, Len(temp) - 1)
temp = Split(temp, "¶")
End If
fGetMatches = temp
End Function
'\d+'
Just add quantifier to \d instead of ' as you want \d to repeat.
Try (?<=')\d+(?=') if you want to get only 277095
See demo.
https://regex101.com/r/iS6jF6/6
Dim strRegex as String = "'\d+'"
Dim myRegex As New Regex(strRegex, RegexOptions.Multiline)
Dim strTargetString As String = "f_details('277095');"
For Each myMatch As Match In myRegex.Matches(strTargetString)
If myMatch.Success Then
' Add your code here
End If
Next
VBScript's regexp implementation is restricted, but if you follow the general rule "Keep it simple", even here you can cut a sequence of numbers easily:
>> Set r = New RegExp
>> r.Pattern = "\d+"
>> s = "f_details('277095');"
>> WScript.Echo r.Execute(s)(0).Value
>>
277095
Additionaly to Vks answer, you can use capturing groups to capture the content you need.
You can use a regex like this:
'(\d+)'
Working demo
You can see highlighted in blue the match and in green the captured content
Match information
MATCH 1
1. [11-17] `277095`

Split a column in a text file

I have a system which generates 3 text (.txt) files on a daily basis, with 1000's of entries within each.
Once the text files are generated we run a vbscript (below) that modifies the files by entering data at specific column positions.
I now need this vbscript to do an additional task which is to separate a column in one of the text files.
So for example the TR201501554s.txt file looks like this:
6876786786 GFS8978976 I
6786786767 DDF78676 I
4343245443 SBSSK67676 I
8393372263 SBSSK56565 I
6545434347 DDF7878333 I
6757650000 SBSSK453 I
With the additional task of seperating the column, data will now look like this, with the column seperated at a specific position.
6876786786 GFS 8978976 I
6786786767 DDF 78676 I
4343245443 SBSSK 67676 I
8393372263 SBSSK 56565 I
6545434347 DDF 7878333 I
6757650000 SBSSK 453 I
I was thinking maybe I could add another "case" to accomplish this with maybe using a "regex" pattern, since the pattern would be only 3 companies to find
(DDF, GFS and SBSSK).
But after looking at many examples, I am not really sure where to start.
Could someone let me know how to accomplish this additional task in our vbscript (below)?
Option Explicit
Const ForReading = 1
Const ForWriting = 2
Dim objFSO, pFolder, cFile, objWFSO, objFileInput, objFileOutput,strLine
Dim strInputPath, strOutputPath , sName, sExtension
Dim strSourceFileComplete, strTargetFileComplete, objSourceFile, objTargetFile
Dim iPos, rChar
Dim fileMatch
'folder paths
strInputPath = "C:\Scripts\Test"
strOutputPath = "C:\Scripts\Test"
'Create the filesystem object
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Get a reference to the processing folder
Set pFolder = objFSO.GetFolder(strInputPath)
'loop through the folder and get the file names to be processed
For Each cFile In pFolder.Files
ProcessAFile cFile
Next
Sub ProcessAFile(objFile)
fileMatch = false
Select Case Left(objFile.Name,2)
Case "MV"
iPos = 257
rChar = "YES"
fileMatch = true
Case "CA"
iPos = 45
rChar = "OCCUPIED"
fileMatch = true
Case "TR"
iPos = 162
rChar = "EUR"
fileMatch = true
End Select
If fileMatch = true Then
Set objWFSO = CreateObject("Scripting.FileSystemObject")
Set objFileInput = objWFSO.OpenTextFile(objFile.Path, ForReading)
strSourceFileComplete = objFile.Path
sExtension = objWFSO.GetExtensionName(objFile.Name)
sName = Replace(objFile.Name, "." & sExtension, "")
strTargetFileComplete = strOutputPath & "\" & sName & "_mod." & sExtension
Set objFileOutput = objFSO.OpenTextFile(strTargetFileComplete, ForWriting, True)
Do While Not objFileInput.AtEndOfStream
strLine = objFileInput.ReadLine
If Len(strLine) >= iPos Then
objFileOutput.WriteLine(Left(strLine,iPos-1) & rChar)
End If
Loop
objFileInput.Close
objFileOutput.Close
Set objFileInput = Nothing
Set objFileOutput = Nothing
Set objSourceFile = objWFSO.GetFile(strSourceFileComplete)
objSourceFile.Delete
Set objSourceFile = Nothing
Set objTargetFile = objWFSO.GetFile(strTargetFileComplete)
objTargetFile.Move strSourceFileComplete
Set objTargetFile = Nothing
Set objWFSO = Nothing
End If
End Sub
You could add a regular expression replacement to your input processing loop. Since you want to re-format the columns I'd do it with a replacement function. Define both the regular expression and the function in the global scope:
...
Set pFolder = objFSO.GetFolder(strInputPath)
Set re = New RegExp
re.Pattern = " ([A-Z]+)(\d+)( +)"
Function ReFormatCol(m, g1, g2, g3, p, s)
ReFormatCol = Left(" " & Left(g1 & " ", 7) & g2 & g3, Len(m)+2)
End Function
'loop through the folder and get the file names to be processed
For Each cFile In pFolder.Files
...
and modify the input processing loop like this:
...
Do While Not objFileInput.AtEndOfStream
strLine = re.Replace(objFileInput.ReadLine, GetRef("ReFormatCol"))
If Len(strLine) >= iPos Then
objFileOutput.WriteLine(Left(strLine,iPos-1) & rChar)
End If
Loop
...
Note that you may need to change your iPos values, since splitting and re-formatting the columns increases the length of the lines by 2 characters.
The callback function ReFormatCol has the following (required) parameters:
m: the match of the regular expression (used to determine the length of the match)
g1, g2, g3: the three groups from the expression
p: the starting position of the match in the source string (but not used here)
s: the source string (but not used here)
The function constructs the replacement for the match from the 3 groups like this:
Left(g1 & " ", 7) appends 4 spaces to the first group (e.g. GFS) and trims it to 7 characters. This is based on the assumption that the first group will always be 3-5 characters long.→ GFS
" " & ... & g2 & g3 prepends the result of the above operation with 2 spaces and appends the other 2 groups (8978976 & ).→ GFS 8978976
Left(..., Len(m)+2) then trims the result string to the length of the original match plus 2 characters (to account for the additional 2 spaces inserted to separate the new second column from the former second, now third, column).→ GFS 8978976
At first replace by regex pattern (\d+)\s+([A-Z]+)(\d+)\s+(\w+) replace with $1 $2 $3 $4
and split that by +. then ok.
Live demo

VBScript RegEx group match with back reference issue

I have a line in my web.config which is as follows
<clientDependency loggerType="xxx.ClientDependencies.Logger,StrattonWebShared" version="144">
What I am trying to do is write a script which checks my code base for modifications and then updates the clientDependency module version by 1 if any found. So the code bit to increase the version by one is as follows
Set clientDepRegExp = new RegExp
clientDepRegExp.IgnoreCase = True
clientDepRegExp.Global = True
clientDepRegExp.Pattern = "(<clientDependency.*version=\"")(\d+)(\"".*)"
'1 = open file for reading
Set clientDependencyConfigFile = fileSystemObject.OpenTextFile(targetFile, 1)
fileContents = clientDependencyConfigFile.ReadAll
clientDependencyConfigFile.Close
fileContents = clientDepRegExp.Replace(fileContents, "$1" & CInt("$2") + 1 & "$3")
My problem is with the last line. $2 is the version number and doing CInt("$2") + 1 is just giving me 3 (so 2 + 1 that is). If I just use "$2" then its returning 144 (refer to the first line for version number). SO my question is if I wana do a quick arithmatic inside replace how should I do it?
Thanks in advance for any tips ans suggestions that you can provide
Change your code something like that:
Set clientDepRegExp = New RegExp
Set fso = New Scripting.FileSystemObject
With clientDepRegExp
.IgnoreCase = True
.Global = True
.Pattern = "(<clientDependency[^<>]*?version="")(\d+)\b"
fileContents = fso.OpenTextFile(targetFile).ReadAll
tmp = .Replace(reftext, "$2")
fileContents = .Replace(reftext, "$1" & CStr(Val(tmp) + 1))
End With
Hope this work.