Design a site like this with WordPress.com
Get started

Regex system app

Can’t believe, it has been an year since I blogged!!!. So, I am back :).

Regular Expression or Regex is a sequence of characters that specifies a match pattern in text. Regex is very powerful though it is not so easy to understand. If you want to know more about Regex in BC world, Areopa webinar or BC Techdays video of David Feldhoff is a must watch.

This post is about the system app Regex. It provides a set of functions that are quite useful when working with text search and replace. If you have a pattern, validations for e-mail, url, phone no. etc. can be done with a single line of code. Four main methods offered by Regex app are IsMatch, Match, Replace and Split. These methods are available with different overloads.

Following Regex expression only extracts ‘date’ from a csv file. This screenshot from regex101.com shows how the matches look like. We do have ‘match’ and ‘group’ tables in regex system app that hold exactly the same data shown here for the below regular expression.

And here is my function:-

  procedure ReadDataFromFile()
    var
        Matches: Record Matches;
        FileManagement: Codeunit "File Management";
        Regex: Codeunit Regex;
        TempBlob: Codeunit "Temp Blob";
        FileInStream: InStream;
        FileLine: Text;
        LineCount: Integer;
        DateRegexLbl: Label '^([1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/[0-9]{4}', Locked = true;
    begin
        ClearSampleLine();
        FileManagement.BLOBImportWithFilter(TempBlob, 'Choose file', '', 'All Files (*.*)|*.*', '*.*');
        if not TempBlob.HasValue() then
            exit;
        TempBlob.CreateInStream(FileInStream);
        while not FileInStream.EOS() do begin
            LineCount += 1;
            if LineCount = 50 then
                break;
            FileInStream.ReadText(FileLine);
            Regex.Match(FileLine, DateRegexLbl, Matches);
            if not Matches.IsEmpty() then
                InsertIntoDemoLineRec(Matches, Regex);
        end;
    end;

This is how we can insert the extracted ‘matches’ into our table.

 procedure InsertIntoDemoLineRec(var TempMatches: Record Matches temporary; var Regex: Codeunit Regex)
    var
        SampleLine: Record "Sample Line";
        TempGroups: Record Groups temporary;
        LineNo: Integer;
    begin
        if TempMatches.IsEmpty() then
            exit;
        if TempMatches.FindSet() then
            repeat
                RegEx.Groups(TempMatches, TempGroups);
                if SampleLine.FindLast() then
                    LineNo := SampleLine."Line No." + 10000
                else
                    LineNo := 10000;
                SampleLine.Reset();
                SampleLine.Init();
                SampleLine."Line No." := LineNo;
                SampleLine.Data1 := TempGroups.ReadValue();
                SampleLine.Insert();
            until TempMatches.Next() = 0;
    end;

If we replace ‘DateRegexLabel’ in the above function with ([^,]*)\S or (,|\r?\n|^)([^",\r\n]+|"(?:[^"]|"")*")? we can loop through every single field in the csv file.

IsMatch function example that validates e-mail:-

  procedure IsValidEmail(InputText: Text): Boolean;
    var
        Regex: Codeunit Regex;
    begin
        exit(Regex.IsMatch(InputText, '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'));
    end;

Of course, you can write a better or more complex regular expression that includes more criteria:).

Replace function is used to replace all strings that match a specified regular expression with a specified replacement string.

   procedure ReplaceDate()
    var
        SampleLine: Record "Sample Line";
        Regex: Codeunit Regex;
        DateRegexLbl: Label '^([1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/[0-9]{4}', Locked = true;
    begin
        if SampleLine.FindSet() then
            repeat
                SampleLine.Data2 := CopyStr(Regex.Replace(SampleLine.Data1, DateRegexLbl, Format(Today)), 1, 80);
                SampleLine.Modify();
            until SampleLine.Next() = 0;
    end;

The following regular expression splits a text into smaller texts of size 60:-

Below function uses the same regex in Split function and returns the result as a list:-

 procedure ParseText(InputText: Text): List of [Text]
    var
        Regex: Codeunit Regex;
        TextArr: List of [Text];
        RegExPattern: Text;
        RegExPatternLbl: Label '([^\n]{1,%1})\s', Locked = true;

    begin
        RegExPattern := StrSubstNo(RegExPatternLbl, 60);
        Regex.Split(InputText, RegExPattern, TextArr);
        exit(TextArr);
    end;

Regex app also provides ‘Escape’ and ‘Unescape’ methods which can be useful when working with Odata webservices though I haven’t tested.

That’s all for now :).

Advertisement

One thought on “Regex system app”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: