web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :

Regular expressions in AL

Jalmaraz Profile Picture Jalmaraz 669

Purposes

1 Introduce, but not explain, regular expressions (Regex hereinafter). But even if I am not going to explain here Regex, I think you don“t have to know a lot about it to follow the AL example.
2 Share regex resources. A special mention to regex101 site https://regex101.com/. With this site you can learn a lot about regex by yourselves, in a comfortable and non-theorical way, with a library of already made regular expressions. For a quick start in regex world is the best choice.
3 Use Regex AL objects in an example.

Regular expressions

Regular expressions are a set of characters that define a search pattern in strings. Regex are usually used to find and search operations or input validations (VAT numbers, post codes, phone numbers, email) checking if the input matches with the defined pattern.
Most user languages as JavaScript, .NET have objects to manage regex, usually with these methods: execute, test, match, and replace. Regex is very useful, but a bit complex and sometimes programmers’ trend to shoehorn it in every string problem, and they donĀ“t fit always for everything, as said Marijn Haverbeke in his book ā€œEloquent JavaScriptā€.
The base concepts of Regex are pattern, grouping, quantification and wildcard. I am not going to explain an over-explained subject as Regex , so here we are some resources for a quick start in regex:
Wikipedia (basics concepts):
Brief, good and free book:
Great and free book, chapter 9 ā€œRegular expressionā€:
And a page to test your own expressions (with a complete breakdown or the results and assistant) and a lot of common use case examples:

AL Regex example

Let`s do an AL example, and breakdown it to know more about Regex management in AL. A good ā€œHello worldā€ for Regex in AL development could be this well-known string problem: variable naming in AL. I mean, replacing this line of code:
        BadNameRecord "Sales Header";
with this line:
        SalesHeaderRecord "Sales Header";
The steps to solve this problem with Regex are:

1 Create a new Codeunit and define the search pattern for the AL object variable declaration

        DeclarationPatternlbl: Label '(.*):\s*(Record|Page|Report|Codeunit|XMLPort|Query)(.*);';
Let“s take a break of AL code and go to a previously recommended page https://regex101.com/ to get a complete analysis of this pattern. This site allow us to save a pattern, and this pattern is saved as https://regex101.com/r/klMsgX/1/. When we open the link, we can see a complete breakdown of the pattern with an example:
3056.Regex.png
In the ā€œExplanationā€ section we can find this pattern breakdown:
Pattern= (.*):\s*(Record|Page|Report|Codeunit|XMLPort|Query)(.*); (In patterns, groups are between parentheses).
1 We have a group (.*): that matches any character until ā€œ:ā€ character.
2 \s* matches any whitespace character.
3 Another group to return object type: (Record|Page|Report|Codeunit|XMLPort|Query). The pipeline means alternative in regex patterns.
4 And the last group, all the characters until the ā€œ;ā€ character: (.*);
In the ā€œMatch informationā€ section we have the match example results, a full match with three groups:
1 Full match: BadName: Record "Sales Header";
2 Group 1: BadName.
3 Group 2: Record.
4 Group 3: "Sales Header".
Now let“s go back to AL Visual Studio Code to continue the example.

2 Create the functions and declare the variable objects we will need:

    procedure RenameALObjectVariable(OriginalStatement: Text) FinalStatement: text;
    var
        DotNet_RegexCodeunit DotNet_Regex;
        DotNet_RegexOptionsCodeunit DotNet_RegexOptions;
        DotNet_MatchCodeunit DotNet_Match;
        DotNet_GroupVarTypeCodeunit DotNet_Group;
        DotNet_GroupVarOldVarNameCodeunit DotNet_Group;
        DotNet_GroupVarSubTypeCodeunit DotNet_Group;
        DotNet_GroupCollectionCodeunit DotNet_GroupCollection;
        NewVarNameText[100];
        NameAlreadyInOldNameBoolean;
All these Al objects are encapsulations of existing DotNet objects that manage regular expressions.

3 Find the AL variable declaration pattern in the string

If you don“t find it, you skip the process with exit statement:
    procedure RenameALObjectVariable(OriginalStatement: Text) FinalStatement: text;
    var
……..
    begin
        FinalStatement := OriginalStatement;
        DotNet_RegexOptions.IgnoreCase();
        DotNet_Regex.Match(OriginalStatement, DeclarationPatternlbl, DotNet_RegexOptions, DotNet_Match);
        if not DotNet_Match.Success() then
            exit;

4 Catch the groups of the match

We have three groups: old variable name, variable type and group subtype.
        DotNet_Match.Groups(DotNet_GroupCollection);
        DotNet_GroupCollection.Item(1, DotNet_GroupVarOldVarName);
        DotNet_GroupCollection.Item(2DotNet_GroupVarType);
        DotNet_GroupCollection.Item(3DotNet_GroupVarSubType);

5 Assemble new declaration statement to return it

This way Badname: Record ā€œSales Headerā€; becomes SalesHeader: Record ā€œSales Headerā€;
        NewVarName := DelChr(DotNet_GroupVarSubType.Value()'=''" ');
        FinalStatement := NewVarName + ': ' + DotNet_GroupVarType.Value() ' ' + DotNet_GroupVarSubType.Value() ';';
 

Comments

*This post is locked for comments