Rob Carlon
Rob Carlon

Reputation: 21

Using VBS Regex to find data in a prior line

I have been working with a file (an ANSI 837 file for those that are interested) that I modify using VBS. One of the modifications requires that I find a date that is contained earlier in the file and I'm trying to avoid having to loop through every line just to get a date.

The file looks roughly like this.

CLM*12345~

DTP*434*RD8*20170101-20170101

*Numerous other lines*

SV2*WXYZ*HC:1234567~

SVD*WXYZ*HC:1234567~

SV2*WXYZ*HC:1234567~

SVD*WXYZ*HC:1234567~

CLM*456789~

DTP*434*RD8*20180101-20180101

*Numerous other lines*

SV2*ABCDE*HC:1234567~

SVD*ABCDE*HC:1234567~

SV2*ABCDE*HC:1234567~

SVD*ABCDE*HC:1234567~

As an example, one requirement might be that I replace any instances of SV2*ABCDE with SV2*EFGHI if the dates in the nearest DTP*434 lines are in 2018. If I do a VBS regex looking for "DTP*434*RD8*2018" through SV2*ABCDE like this:

(DTP\*434\*RD8\*)(.*)(~[\s\S]*?SV2\*)

Then I get the first DTP line from the file rather than the nearest one. Since VBS doesn't support lookbehind, I have also tried to write something that would only match if it didn't encounter CLM* between the DTP*434 and the SV2 line, but I can't seem to get negative lookahead to work either nor can I find good documentation for negative lookahead in VBS.

Upvotes: 1

Views: 179

Answers (1)

omegastripes
omegastripes

Reputation: 12602

VBS RegExp pattern template to find a string not containing another string looks in general like:

beginning(?:(?!excluding)[\s\S])*?ending

You may try the below code to replace any instances of SV2*ABCDE with SV2*EFGHI if the dates in the nearest DTP*434 lines are in 2018 (supposed there are source.txt and result.txt text files in Unicode):

Dim sContent, sReplace

sContent = ReadTextFile("C:\test\source.txt", -1)

With CreateObject("VBScript.RegExp")
    .Global = False
    .Multiline = True
    .IgnoreCase = True
    .Pattern = "(DTP\*434\*RD8\*2018\d{4}-2018\d{4}(?:(?!DTP\*434\*RD8\*)[\s\S])*?SV2\*)ABCDE(\*)"
    Do
        sReplace = .Replace(sContent, "$1EFGHI$2")
        If sReplace = sContent Then Exit Do
        sContent = sReplace
    Loop
End With

WriteTextFile sReplace, "C:\test\result.txt", -1

Function ReadTextFile(sPath, lFormat)
    ' lFormat -2 - System default, -1 - Unicode, 0 - ASCII
    With CreateObject("Scripting.FileSystemObject").OpenTextFile(sPath, 1, False, lFormat)
        ReadTextFile = ""
        If Not .AtEndOfStream Then ReadTextFile = .ReadAll
        .Close
    End With
End Function

Sub WriteTextFile(sContent, sPath, lFormat)
    ' lFormat -2 - System default, -1 - Unicode, 0 - ASCII
    With CreateObject("Scripting.FileSystemObject").OpenTextFile(sPath, 2, True, lFormat)
        .Write sContent
        .Close
    End With
End Sub

These links may be helpful: MSDN Introduction to Regular Expressions (JavaScript) and RegexBuddy VBScript’s Regular Expression Support.

Upvotes: 1

Related Questions