Search code examples
vbscriptg-code

Replace instances of certain string in between two strings


I am trying to create a VBScript to find and replace a certain string located between two strings. Here is an example of a file that the script will be executed on:

%
N1 ( POSTED FILE NAME - WORKNC POST )
N2 ( INPUT FILE NAME - _6033_Cavity__01.TBA)
N3 (DATE/TIME: Thu Mar 15 06:36:08 2018)
N4 G0 G40 G80 G90 G98
N5 G17
N6 G57H901
N7 G173W0.0
N8 B0.000
N9 (Tapper 0.250000)
N10 T21
N11 M06
N12 S100
N13 M843
N14 G173 W0.0
N15 (- )
N16 ( Tapping )
N17 G0 G90 X-0.0001 Y8.8135
N18 G43 Z10.0632 H21
N19 G01 F500. X-0.0001 Y8.8135
N20 G01 Z9.7163 F500.
N21 G98 G84 X-0.0001 Y8.8135 Z6.0376 R7.6376 E10.
N22 G80 G01 F500.
N23 X-0.0001 Y8.8135 Z9.7163
N24 X-0.0001 Y8.8135 Z9.7163
N25
N26 M845
N27 G91 G28 Z0
N28 G90
N29 G57H901
N30 G173W0.0
N31 B0.000
N32 (Drill 0.005000)
N33 T19
N34 M06
N35 S5000
N36 M3
N37 G173 W0.0
N38 (- )
N39 ( Contour Chamfer )
N40 G0 G90 X-0.0001 Y8.8135
N41 G43 Z9.7163 H19
N42 Z7.6375
N43 G01 Z9.8376 F500.
N44 X-0.0001 Y8.8135 Z10.0632
N45
N46 M05
N47 G91 G28 Z0
N48 G90
N49 G57H901
N50 G173W0.0
N51 B0.000
N52 (Tapper 0.750000)
N53 T21
N54 M06
N55 S100
N56 M843
N57 G173 W0.0
N58 (- )
N59 ( Tapping )
N60 G0 G90 X-0.0001 Y8.8135
N61 G43 Z10.0632 H21
N62 G01 F500. X-0.0001 Y8.8135
N63 G01 Z9.7163 F500.
N64 G98 G84 X-0.0001 Y8.8135 Z6.0376 R7.6376 E10.
N65 G98 G84 X-0.0001 Y10.8135 Z6.0376 R7.6376 E10.
N66 G80 G01 F500.
N67 X-0.0001 Y8.8135 Z9.7163
N68 X-0.0001 Y8.8135 Z9.7163
N69
N70 M845
N71 G91 G28 Z0
N72 G90
N73 M30
%

So in this particular code there are two Tapping operations. I am trying to make a script that looks between Tapper 0.250000 and M845, and replaces all instances of E10. with a variable that will be based on the number in Tapper 0.250000.

So for example lets say there is Tapper 0.250000 and some X lines later M845, the E10.'s that occur between those two need to be replaced with E0.250000. If there is another tapping operation such as Tapper 0.750000 the E10.'s that are in between the Tapper and M845 need to be replaced with E0.787.

Here is my VBScript so far:

strFileName = Wscript.Arguments(0)
strOutputFile = Wscript.Arguments(0)

Set fso = CreateObject("Scripting.FileSystemObject")

'Variable patterns to search for. There may be 9 of these total
strPattern25 = "(Tapper 0.250000)(.|\s)*(M845)"
strPattern375 = "(Tapper 0.375000)(.|\s)*(M845)"
strPattern5 = "(Tapper 0.500000)(.|\s)*(M845)"
strPattern75 = "(Tapper 0.750000)(.|\s)*(M845)"

strFindString = "E10." 'String to find and then replace each instance of between pattern

'Variables of the replace string
strReplaceString25 = "E0.05"
strReplaceString375 = "E0.0625"
strReplaceString5 = "E0.0769"
strReplaceString75 = "E0.787"

strTestString = fso.OpenTextFile(strFileName, 1).ReadAll 'open and read the file

'Replacing script. Currently replaces all text between the strPattern. Need to create another function in order to only replace the E10.
strNewText25 = fReplaceText(strPattern25, strTestString, strReplaceString25)
strNewText375 = fReplaceText(strPattern375, strTestString, strReplaceString375)
strNewText5 = fReplaceText(strPattern5, strTestString, strReplaceString5)
strNewText75 = fReplaceText(strPattern75, strTestString, strReplaceString75)

fso.OpenTextFile(strOutputFile, 2, True).WriteLine strNewText

MsgBox "Done!"

'Function
Function fReplaceText(sPattern, sStr, sReplStr)
    Dim regEx, oMatch, 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 = ""
    Else
        For Each oMatch In colMatches
            temp = regEx.Replace(sStr, oMatch.SubMatches(0) & vbCrlf & sReplStr & vbCrlf & oMatch.SubMatches(2))
        Next
    End If
    fReplaceText = temp
End Function

Solution

  • I used the following approach to get the desired result:

    • read all the contents of the File
    • grab all the substrings beginning with Tapper <some digits> and ending with M845 using regular expressions
    • In each substring, replace all the instances of E10 with E<some digits>
    • Write the modified substring back to the file

    Take help from this code:

    Option Explicit
    Dim strFilePath, objFso, objFile, strFileContents, objReg, objMatches, i, strTemp, strNew
    strFilePath  = "C:\Users\gurmansingh\Desktop\Test\inout.txt"            'Give the appropriate file path here or use the arguments, like you are using now
    Set objFso = CreateObject("scripting.filesystemobject")
    Set objFile = objFso.OpenTextFile(strFilePath,1,False)
    strFileContents = objFile.ReadAll                                       'Reading all the contents of the File. Note that this method of reading will prove to be a bit inefficient when the file size is large
    objFile.Close
    
    Set objReg = New RegExp
    objReg.Global = True
    objReg.Pattern = "Tapper\s*(\d*(?:\.\d+)?)[\s\S]*?M845"                 'Pattern Explained later
    Set objMatches = objReg.Execute(strFileContents)                        'Finds all the substrings in the file that matches the above Regex Pattern
    For i=0 To objMatches.Count-1
        strTemp = objMatches.Item(i).Submatches.Item(0)                     'Grabbing the digits that come after the text 'Tapper '
        strNew = Replace(objMatches.Item(i),"E10","E"&strTemp)              'Replacing all the E10's in each match
        strFileContents = Replace(strFileContents,objMatches.Item(i),strNew)
    Next
    Set objFile = objFso.OpenTextFile(strFilePath,2,False)
    objFile.Write strFileContents
    objFile.Close
    Set objFile = Nothing
    Set objFso = Nothing
    

    Regex Explanation:

    Tapper\s*(\d*(?:\.\d+)?)[\s\S]*?M845
    
    • Tapper\s* - matches the text Tapper followed by 0+ white-spaces
    • (\d*(?:\.\d+)?) - matches and captures a sequence of digits in Group 1. Whatever is captured in this group, will be used later for the replacing the E10
    • [\s\S]*? - matches 0+ occurrences of any character, as few as possible
    • M845 - matches M845

    Click here for Regex Demo