Skip to content

Mask Syntax: Basics

Egor Taflanidi edited this page Jul 28, 2023 · 1 revision

The library uses its own syntax for input masking patterns, each pattern is essentially a string with special characters.

Patterns describe which parts of the input are arbitrary, and which are constant.

Patterns also describe which parts of the input are valuable, and which are there just for the user's convenience.

So, for instance, imagine your app has a field for a phone number:

+1 (098) 765-43-21

The API behind the app awaits a phone number including the country code:

{
    "phone": "+10987654321"
}

A mask for such a field would be:

{+1} ([000]) [000]-[00]-[00]

Country code, brackets, spaces and dashes are constant:

+1 (   )    -  -  

User-entered digits are arbitrary:

    098  765 43 21

At the same time, user-entered digits and the country code are valuable:

+1  098  765 43 21

Each time the text field is edited, you'll be able to get valuable parts of the string separately from everything else.

KeyPressed    Output                Extracted

%tap%         +1                    +1
0             +1 (0                 +10
9             +1 (09                +109
8             +1 (098)              +1098
7             +1 (098) 7            +10987
6             +1 (098) 76           +109876
5             +1 (098) 765-         +1098765
4             +1 (098) 765-4        +10987654
3             +1 (098) 765-43-      +109876543
2             +1 (098) 765-43-2     +1098765432
1             +1 (098) 765-43-21    +10987654321

The valuable arbitrary parts of the string are called "placeholder blocks".
The valuable constant parts are called "constant blocks".
Other parts are just called "separators".

Placeholder blocks

[]

These blocks of symbols allow one to enter arbitrary letters, digits, etc.
Entered characters end up in the output and are included in the extracted value.

Square brackets may contain any number of special symbols:

  1. 0 — mandatory digit. For instance, [000] will allow entering three digits: 123.
  2. 9 — optional digit. For instance, [00099] will allow entering up to five digits, but at least three.
  3. А — mandatory letter. [AAA] will allow entering three letters: abc.
  4. а — optional letter. [АААааа] will allow entering from three to six letters.
  5. _ — mandatory symbol (digit or letter).
  6. - — optional symbol (digit or letter).
  7. — ellipsis. Allows you to enter an endless amount of symbols. For details and rules see Elliptical masks.

Other symbols inside square brackets will cause a mask initialization error and will throw an exception unless you have used custom notations.

Blocks may contain mixed types of symbols; such that, [000AA] will end up being divided into two groups: [000][AA] (this happens automatically). Though, it's highly recommended not to mix default symbols with symbols defined by custom notations.

Blocks must not contain nested brackets. [[00]000] format will cause a mask initialization error and will throw an exception.

Optional symbols

Please note that the optional symbols like 9 or a do represent a range of input lengths, during which the extracted value completeness remains constant.

For instance, let's say you have a year field. While inputs like 98 (1998) and 2012 are entirely acceptable, with a mask like [0099] you'll end up in a situation when 615 is accepted, too:

Input   Complete

1       False
19      True        # 2019
199     True        # STILL TRUE
1992    True

In order to restrict invalid values from being accepted, you've got to use affine masks. Affine masks are switched on the fly depending on the input, and each mask will have its own number of mandatory digits:

Input   Complete    Current Mask

1       False       [00]
19      True        [00]
199     False       [0000]
1992    True        [0000]

Constant blocks

{}

Everything inside curly brackets is included in both output and extracted value.
These symbols cannot be altered. Such that, with the mask like

[00]{/}[09]

you will always have a / slash:

Input   Output   Extracted   Complete

1       1        1           False
12      12       12          False
12/     12/      12/         False
12/3    12/3     12/3        True
12/34   12/34    12/34       True

Separators

 

Separators, or "free characters", are everything outside the square and curly brackets.
Separators appear in the output but are not included in the extracted value.

Effectively, separators are constant blocks not invited into the extracted value.
Such that, masks like [00]-[00] and [00]{-}[00] will lead to the same output.

Mask          Output   Extracted

[00]-[00]     12-34    1234
[00]{-}[00]   12-34    12-34

Elliptical masks

Ellipsis allows one to enter endless line of symbols of a specific type. Ellipsis "inherits" its symbol type from the previous character in the format string. Masks like [A…] or [a…] will allow to enter letters, [0…] or [9…] — numbers, etc.

Just to let you know, ellipsis does not count as a required character. Also, ellipsis works as a string terminator, such that mask [0…][AAA] filled with a single digit returns true in Result.complete, yet continues to accept digits (not letters!). Characters after the ellipsis are compiled into the mask but never actually used; [AAA] part of the [0…][AAA] mask is pretty much useless.

Elliptical mask examples:

  1. […] is a wildcard mask, that allows one to enter letters and digits. Always returns true in Result.complete.
  2. [00…] is a numeric mask, allowing one to enter digits. Requires at least two digits to be complete.
  3. [9…] is a numeric mask, allowing one to enter digits. Always returns true in Result.complete.
  4. [_…] is a wildcard mask with a single mandatory character. Allows to enter letters and digits. Requires a single character (digit or letter).
  5. [-…] acts same as […].

Elliptical masks support custom notations, too.

Character escaping

Masks support backslash escapes when you need square or curly brackets in your output.
For instance, a \[[00]\] mask will allow entering [12]. The extracted value will be equal to 12.

Note that you've got to escape backslashes in the actual code:

let format: String = "\\[[00]\\]"

Escaped square or curly brackets might be included in the extracted value. For instance, \[[00]{\]} mask will allow entering the same [12], yet the extracted value will contain the latter square bracket: 12].