Regular Expressions in NAV

A friend of mine recently asked if there was a standard NAV function to find the first alphabetical character in a string. STRPOS comes close but you can't say "tell me the first position for any one of these characters in this string" because it looks for an exact match of the substring and not any character from the substring.

The AL code to do this isn't hard but I figured this was a perfect excuse to play with the new .NET Interop feature in NAV 2009 R2.

With the release of NAV 2009 R2, we have the ability to use the . NET Framework directly from within AL code. Now we can use simple .NET classes to do things with strings that previously required several lines of code. I'm thinking of regular expressions of course.

The regular expression for any character between A and Z or a and z is [A-Z,a-z].

I created a function in a Codeunit called RegExFind that takes two parameters (a string to be search and a string containing the regular expression to match on). It returns an Integer which is the matching position of the first matching character (it returns 0 if it doesn't find a match).

To run the code, you need to add the Codeunit to a RoleTailored MenuSuite as .NET Interop only works on the service tier. You could put this code in a button on a page too, if you wish.

Here is the function:


RegExFind(SearchString : Text[250];RegEx : Text[250]) : Integer

dnMatch := dnRegEx.Match(SearchString,RegEx);

IF dnMatch.Success THEN
  EXIT(dnMatch.Index+1)
ELSE
  EXIT(0);

 

In my Function I have the following local variables:

Name DataType Subtype
dnRegEx DotNet 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.RegularExpressions.Regex
dnMatch DotNet 'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.RegularExpressions.Match

 

Notice that we return the Index +1 (as in .NET all arrays start at 0 where in AL they start at 1).

The code to call the function is shown here:


SearchString := '1234 Lines of Code';

FoundPos := RegExFind(SearchString,'[a-z,A-Z]');

IF FoundPos > 0 THEN
  MESSAGE ('Found %1 at position %2 in %3',COPYSTR(SearchString,FoundPos,1),FoundPos,SearchString);


SearchString := 'Now I look for 1 or 2 numbers.';

FoundPos := RegExFind(SearchString,'[0-9]');

IF FoundPos > 0 THEN
  MESSAGE ('Found %1 at position %2 in %3',COPYSTR(SearchString,FoundPos,1),FoundPos,SearchString);

 

As you would expect, when I run this Codeunit from my RoleTailored client, I get the following output:

 

image

image

 

The only problem with the new .NET Interop is knowing what's out there in the framework. The chances are, there's something to handle your requirement and the good news is there'll be plenty of examples of how to use it - just as long as you can translate the C# code into an AL equivalent.

This simple example is just the tip of the iceberg for what you can do with regular expressions. Wouldn't it be nice to use regular expressions to validate user input?

Have you got any favourite .NET tricks that you’d like to do in AL code?


Related
Recommended