PowerApps IsMatch Function Explained (plus Match & MatchAll)

PowerApps IsMatch Function

The IsMatch function in PowerApps lets you check, whether a string matches a given format or not. It is very powerful when comes to validating a user’s text input within a form.

For instance the user needs to provide an email address. PowerApps IsMatch can check if the provided email has the correct format of an email address. Other common use cases might be a phone number, a website’s URL or any kind of IDs.

The IsMatch function lets you use simple text snippets, regular expressions and predefined matchers.

This guide explains the IsMatch function and offers common examples for use cases like the mentioned email, phone number, URL and more.

The IsMatch function compares a text against a given pattern. The pattern can be simple text snippets, regular expressions, predefined patterns or a combination of multiple predefined patterns. Its outcome is ‘true’ in case the text matches the pattern and ‘false’ in case the pattern is not matched.

Syntax

IsMatch( Text, Pattern [, Options ] )

Input parameters

  • Text (mandatory): The text you want to validate against a pattern.
  • Pattern (mandatory): A pattern for matching the given text. Note: As for now, the pattern string must be constant. A variable in the IsMatch pattern is not allowed.
  • Options (optional): The option lets you specify how the pattern is applied. Allowed entries are all the value of the MatchOptions enumerations, which are BeginsWith | Contains | EndsWith | IgnoreCase | Multiline | Complete (default)

Return value

  • true: If the pattern is matched
  • false: If the pattern is NOT matched

Predefined Patterns

Regular expressions are hard to read and maintain for someone who is not using them on a daily basis. Therefore Microsoft provides a couple of predefined patterns that represent a regular expressions with self explaining names. These predefined patterns can be combined with the ‘&’ as shown below:

// example to validate a price with predefined patterns
IsMatch( 
  "21.78",
  MultipleDigits & Period & Digit & Digit
); // => true

To get an overview of the existing predefined patterns and how to use them. Here are some examples.

Sepcial

There predefined patterns for common special characters like comma, hyphen and period. Additionally there is a matcher for any, that can be any character (any = 1 character).

  • Any
  • Comma
  • Hyphen
  • Period

Here is one example to demonstrate the usage.

IsMatch(
  "!,-.",
  Any & Comma & Hyphen & Period
) // => true

Letters

For letters there are three dedicated predefined patterns:

  • Letter
  • MultipleLetters
  • OptionalLetters

Here are two examples how to use them:

IsMatch(
  "a.abc.as",
  Letter & Period & MultipleLetters & Period & OptionalLetters
); // => true

IsMatch( 
  "a.abc.",
  Letter & Period & MultipleLetters & Period & OptionalLetters
); // => true

Digits

For digits there are corresponding predefined patterns:

  • Digit
  • MultipleDigits
  • OptionalDigits

Usage is basically the same as for the the letter patterns:

IsMatch( 
  "1.123.1",
  Digit & Period & MultipleDigits & Period & OptionalDigits
) // => true

IsMatch( 
  "1.123.",
  Digit & Period & MultipleDigits & Period & OptionalDigits
) // => true

Spaces

For spaces there are a couple of predefined matchers.

  • MultipleNonSpaces(1 or multiple characters that are not space)
  • MultipleSpaces (1 or multiple spaces)
  • NonSpace (1 character that is not space)
  • OptionalNonSpaces (0 or multiple characters that are not space)
  • OptionalSpaces (0 or 1 space)
  • Space (one whitespace)

Here is an example using all predefined patterns for spaces.

IsMatch(
    "a1.  .a.. . ", 
    MultipleNonSpaces & Period & MultipleSpaces & Period & NonSpace & Period & OptionalNonSpaces & Period &  OptionalSpaces & Period &  Space
) // => true

Parenthesis

There are only predefined matchers for classic parenthesis:

  • LeftParen
  • RightParen

The usage is easy to understand:

IsMatch(
  "(123)", 
  LeftParen & MultipleDigits & RightParen
) // => true

Email

For emails there is one predefined matcher:

  • Email

The usage explains itself:

IsMatch(
  "[email protected]",
  Email
) // => true

Match Options

Complete

In contrast to the Contains option, per default the Complete option is set for IsMatch. This means that there must be an exact match.

IsMatch( 
  "abc",
  "abc"
); => true

IsMatch( 
  "abc",
  "ab"
); => false

Contains

The Contains option defines, that the match evaluates to true, in case the match is found somewhere within the text.

IsMatch( 
  "abc",
  "ab",
  Contains
); => true

BeginsWith & EndsWith

The BeginsWith option only evaluates to true, if the pattern is matched at the beginning of the string.

IsMatch( 
  "abc",
  "a",
  BeginsWith
); => true

IsMatch( 
  "abc",
  "b",
  BeginsWith
); => false

The EndsWith option only evaluates to true, if the pattern is matched at the end of the string.

IsMatch( 
  "abc",
  "c",
  EndsWith
); => true

IsMatch( 
  "abc",
  "a",
  EndsWith
); => false

IgnoreCase

To turn off case sensitivity for matches use the IgnoreCase option. Matches will evaluate to true, no matter if lower case or upper case is used.

// IsMatch with IgnoreCase options
IsMatch( 
  "ABC",
  "abc",
  IgnoreCase
); => true

// IsMatch without IgnoreCase options
IsMatch( 
  "ABC",
  "abc"
); => false

Special characters

Pattern can be simple text matches:

IsMatch("abc","abc"); // => true

Pattern can also be regular expressions:

IsMatch( "123", "\d+" ); // => true

Within regular expressions some characters have a special meaning (like ‘\’ and ‘+’ in the example).

To not trigger the special meaning, you have to escape these characters in case you do not want to trigger the regular expression behavior with a backslash ‘\’ like this:

// escaping of special characters is missing, does not match
IsMatch(
  "(1 + 2) * 1 = 3 ?",
  "(1 + 2) * 1 = 3 ?"
);  // => false

// correct escaping of special characerts 
IsMatch(
  "(1 + 2) * 1 = 3 ?",
  "\(1 \+ 2\) \* 1 = 3 \?"
); // => true

List of special characters

These are all characters you need to escape with backslash:

  • . (dot or period)
  • ? (question mark)
  • * (asterisk)
  • + (plus)
  • ( ) (parentheses)
  • [ ] (square brackets)
  • { } (curly braces)
  • ^ (caret)
  • $ (dollar sign)
  • | (vertical bar or pipe)
  • \ (backslash)

IsMatch Variable in Pattern

Unfortunately the pattern string can not be a variable. Something like this will not work:

Set(POSITIVE_NUMBER_REGEX,"\d+");
IsMatch( "123",  POSITIVE_NUMBER_REGEX); // !! Not allowed !!

This will cause an error of type “Regular expressions must be constant values”.

Error “Regular expressions must be constant values.”

Hopefully this will change in the future. At the moment it is not supported to use variables within patterns.

IsMatch And Delegation

IsMatch is not a delegable function. Therefore you should not use IsMatch function on large data sets no matter which data source you use. For instance look for delegable alternatives for IsMatch in Filter or Lookup function calls on SharePoint Lists like ‘=’,'<>’, StartsWith etc.

PowerApps IsMatch Examples

Not IsMatch

Sometimes you want to check if it is NOT a match. This can be achieved by using the exclamation mark or the Not function as shown in the following IsMatch examples.

// exclamation mark
!IsMatch("abc", "abc"); // => false

// Not function
Not(IsMatch("abc", "abc")); // => false

IsMatch Regular Expression

Regular expressions are very powerful. You can find regular expressions for most formats within the web. Nevertheless they are hard to read and to formulate. Here is very basic example for positive numbers.

IsMatch( "123", "\d+" ); // => true

IsMatch Date

Within a form the best way to ensure that there is the correct date format is to provide a date field controlled by a calendar control. Nevertheless there can be cases where you need to ensure that a string has a correct certain date format.

Date formats do differ in different countries and there are different formats used.

The following scripts show how to validate some of the more common date formats with regular expressions.

// YYYY-MM-DD
IsMatch("2022-02-23","\d{4}-\d{2}-\d{2}"); // => true

// YYYY/MM/DD
IsMatch("2022/02/23","\d{4}/\d{2}/\d{2}") // => true

// MM/DD/YYYY 
IsMatch("04/21/2008","\d{2}/\d{2}/\d{4}"); // => true

// MM-DD-YYYY 
IsMatch("04-21-2008","\d{2}-\d{2}-\d{4}"); // => true

IsMatch Time

Due to the variety of time formats, there is not one time pattern to rule them all. By using regular expressions, you can define your time format. The following expression can be used as a starting point.

IsMatch("11:00 AM", "\d{1,2}\:\d{2}\ (AM|PM)"); // => true

IsMatch("4:00 PM", "\d{1,2}\:\d{2}\ (AM|PM)"); // => true

IsMatch Email

IsMatch("[email protected]", Match.Email); // => true

IsMatch Phone Number

The format of telephone numbers differ from country to country. To validate a telephone number with the IsMatch function, you can use a regular expression. The following example can be used for American phone number format.

In case you need the regular expression for another country, search the internet for the regular expression for your country’s phone number format. Feel free to let me know your findings, so I can add them here for others.

// Validate North American Phone Numbers
IsMatch(
  "123-456-7890", 
  "^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"
); // => true

Source of regular expression: O’REILLY Regular Expressions Cookbook

IsMatch URL

This is an example of an IsMatch for a http-URL. Note that only ‘http’ and ‘https’ will match. Other protocols like ‘ftp’ will not match.

IsMatch(
  "https://zeitgeistcode.com", 
  "(https?:\/\/(www\.)?[[email protected]:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))"
) // => true

Match & MatchAll Function

It is essential to understand the IsMatch function to understand Match & MatchAll function, because of the big overlap of the functions. Everything you need to know is explained above.

The difference between IsMatch anf Match/MatchAll is, that IsMatch just checks, if pattern is matched. Match/MatchAll return the pattern match(es). So IsMatch is good for validating some input. Match/MatchAll are good for finding matches within a text.

The difference between the Match function and the MatchAll function is that Match returns the first match and MatchAll returns all matches.

Syntax

Match( Text, Pattern [, Options ] )
MatchAll( Text, Pattern [, Options ] )

Input parameters

  • Text (mandatory): The text you want to validate against a pattern.
  • Pattern (mandatory): A pattern for matching the given text. Note: As for now, the pattern string must be constant. A variable in the IsMatch pattern is not allowed.
  • Options (optional): The option lets you specify how the pattern is applied. Allowed entries are all the value of the MatchOptions enumerations, which are BeginsWith | Contains (default) | EndsWith | IgnoreCase | Multiline | Complete

Return Value of Match Function

  • If a match is found: Match function returns a Record with following columns:
    • named sub‑match or sub‑matches: In case there are any named matches or unnamed submatches, there will columns for them (see examples below)
    • FullMatch: String of the matched text.
    • StartMatch: Start index of the matches string (starting at 1 for first string)
    • SubMatches: Table of submatches
  • If NO match is found: Match function returns blank

Match function examples

Simple match

In the following example we are looking for a digit. The digit is the ‘1’ the 5th character.

Set(
    myMatchtes,
    Match(
        "paul1",
        Digit 
    )
);

// matches a digit

/* Result:

{
  FullMatch: "1"",
  StartMatch: 5,
  Submatches: {}
}

*/

Named submatches

You can name submatches by using the format (?<name>REGEX). In the example there are two named submatches: One for the email called ‘mail’ and one for the ‘age’.

Set(
    myMatchtes,
    Match(
        "[email protected];32",
        "(?<mail>" & Email & ");(?<age>" & Digit & Digit & ")"
    )
);

/*

{
   mail: "[email protected]",
   age: "32"",
   FullMatch: "[email protected];32",
   StartMatch: 1,
   SubMatches: 
     {
       "[email protected]",
       age: "32"
     }

}
*/

MatchAll example

Match all returns all the matches within the text. Since we are looking for a digit and there are two digits in the text, we get two matches.

Set(
    myMatchtes,
    MatchAll(
        "paul1a4",
        Digit 
    )
);

/*
{
  {
    FullMatch: "1"",
    StartMatch: 5,
    Submatches: {}
  },
  {
    FullMatch: "4",
    StartMatch: 7,
    Submatches: {}
  }
}
*/

Leave a Comment

Your email address will not be published.