Regular Expression (REGEX) Support


Regular Expression Definition

 

Regular expressions, usually called regex, are patterns used to search, validate, extract, or replace text. These expressions can be used within a PL/B expression, in the DATAFILTER property, in the FILTER instruction, and the PL/B REGEX object.

 

For example, the regex string:

 

      \d{5}

 

matches exactly five digits, such as:

 

      12345

      90210

 

Basic Characters

 

Most ordinary characters match themselves.

 

      cat

 

Matches:

 

      cat

 

It would also match the cat portion of:

 

      catalog

      the cat sleeps

 

Character Classes

 

Square brackets let you match one character from a group.

 

Pattern

Meaning

[abc]

Match one listed character

[^abc]

Match one character not in the listed set

[a-zA-Z]

Match one character in one of the listed ranges

 

Example:

 

      [abc]

 

Matches:

 

      a

      b

      c

 

Ranges can also be used:

 

      [a-z]

 

Matches any lowercase letter.

 

      [A-Z]

 

Matches any uppercase letter.

 

      [0-9]

 

Matches any digit.

 

You can combine ranges:

 

      [a-zA-Z0-9]

 

Matches any letter or digit.

 

To match anything except the listed characters, use `^` inside the brackets:

 

      [^0-9]

 

Matches any character that is not a digit.

Common Shortcuts

 

Regex provides several useful shorthand character classes.

 

Pattern

Meaning

\d

Digit: 0-9

\D

Anything except a digit

\s

Whitespace: space, tab, form feed, carriage return, line feed, vertical tab

\S

Anything except whitespace

\w

Word character: Letter, digit, or underscore [A-Za-z0-9_]

\W

Anything except a word character

.

Any character except new line, carriage return and null

 

Example:

 

      \d\d\d

 

Matches three digits:

 

      123

      456

      789

Repetition

 

Instead of repeating a pattern manually, regex provides repetition operators.

 

Pattern

Meaning

*

Match zero or more

+

Match one or more

?

Match zero or one

Zero or more

 

      a*

 

Matches zero or more 'a' characters.

 

Examples:

 

      ""

      a

      aa

      aaa

One or more

 

      a+

 

Matches one or more 'a' characters.

 

Examples:

 

      a

      aa

      aaa

Zero or one

 

      a?

 

Means the character is optional.

 

It matches:

 

      ""

      a

 

A practical example is:

 

      colou?r

 

This matches both:

 

      color

      colour

Exact Repetition

 

Curly braces specify how many times something should occur.

 

Pattern

Meaning

{n}

Match exactly n

{n,}

Match n or more

{n,m}

Match from n to m

 

Example:

 

      \d{4}

 

Matches exactly four digits:

 

      2026

      1234

 

A range can also be specified:

 

      \d{2,4}

 

Matches between two and four digits.

 

Examples:

 

      12

      123

      1234

 

To specify a minimum with no maximum:

 

      \d{2,}

 

This means two or more digits.

Anchors

 

Pattern

Meaning

^

Match start of string

$

Match end of string

\b

Match a word boundary (\w or [A-Za-z0-9_])

\B

Match a non-word boundary

 

Beginning and End of Text

 

The caret '^' normally means start of the string.

 

      ^Hello

 

Matches:

 

      Hello world

 

but not:

 

      Say Hello

 

The dollar sign '$' means end of the string.

 

      world$

 

Matches:

 

      Hello world

 

but not:

 

      world today

 

They are often combined when validating an entire value.

 

      ^\d{5}$

 

This means:

 

      start

      five digits

      end

 

So:

 

      12345

 

matches, but:

 

      ABC12345

      123456

      12345ABC

 

do not.

 

In multiline mode, '^' and '$' also match at new line boundaries.

Word Boundaries

 

'\b' represents a word boundary.

 

      \bcat\b

 

Matches:

 

      The cat sleeps.

 

but does not match the 'cat' inside:

 

      catalog

      education

 

This is useful when searching for complete words.

 

On an empty input string, '\b' does not match.

Groups

 

Parentheses group parts of a regular expression. Repetition can follow after groups.

 

      (abc)

 

Groups 'abc' together.

 

Groups become especially useful with repetition:

 

      (ab)+

 

Matches:

 

      ab

      abab

      ababab

OR Conditions

 

The pipe character '|' means OR.

 

      cat|dog

 

Matches either:

 

      cat

 

or:

 

      dog

 

Grouping is often useful:

 

      ^(cat|dog)$

 

This matches exactly either 'cat' or 'dog'.

Escaping Special Characters

 

Several characters have special meanings in regex:

 

      . ^ $ * + ? ( ) [ ] { } | \

 

If you want to match one of them literally, usually place a backslash before it.

 

For example:

 

      \.

 

matches an actual period.

 

So:

 

      example\.com

 

matches:

 

      example.com

 

Another example:

 

      \$

 

matches an actual dollar sign.

 

Some escapes have special meaning as shown below:

 

 

Escape

Meaning

\n

New line

\r

Carriage return

\t

Tab

\v

Vertical tab

\f

Form feed

\0ooo

Octal byte escape

\xhh

Hex byte escape

Extracting Information

 

Regex can also locate portions of larger text.

 

Suppose you have:

 

      Order Number: 123456

 

The pattern:

 

      \d+

 

finds:

 

      123456

 

If your text is:

 

      Customer ID: CUST12345

 

you could use:

 

      CUST\d+

 

to extract:

 

      CUST12345

Greedy vs. Lazy Matching

 

Regex repetition is normally greedy, meaning it tries to match as much as possible.

 

Consider:

 

      <.*>

 

against:

 

      <b>Hello</b><i>World</i>

 

It matches the entire string.

 

Adding '?' makes the repetition lazy:

 

      <.*?>

 

This causes it to stop at the earliest possible match.

 

It can separately find:

 

     <b>

     </b>

     <i>

     </i>

 

Greedy:

 

Pattern

Meaning

*

Match zero or more

+

Match one or more

?

Match zero or one

{n}

Match exactly n

{n,}

Match n or more

{n,m}

Match from n to m

 

Lazy:

 

Pattern

Meaning

*?

Match zero or more, lazy

+?

Match one or more, lazy

??

Match zero or one, lazy

{n,}?

Match n or more, lazy

{n,m}?

Match from n to m, lazy

 

Capturing Groups

 

Parentheses can capture pieces of a match. Captures are numbered by opening parenthesis order.

 

For example:

 

      (\d{3})-(\d{3})-(\d{4})

 

Applied to:

 

      555-123-4567

 

produces three groups:

 

      Group 1 = 555

      Group 2 = 123

      Group 3 = 4567

 

This is very useful when parsing structured text.

 

To reference a previously defined capturing group, the '\1' to '\9' patterns can be used.

 

To make a group non-capturing, the '?:' character pair is used at the start of the group. Non-capturing groups behave like normal groups for matching, alternation, and quantifiers, but they do not create a capture slot and do not affect capture numbering.

 

Pattern

Meaning

(...)

Capturing group

(?:...)

Non-Capturing group

\1..\9

Reference a previously defined capturing group

POSIX Character Classes

 

POSIX character classes are supported inside bracket expressions.

 

Pattern

Meaning

[:upper:]

Upper case letters

[:lower:]

Lower case letters

[:alpha:]

All letters

[:alnum:]

Digits and letters

[:digit:]

Digits

[:xdigit:]

Hexadecimal digits

[:punct:]

Punctuation

[:blank:]

Space and tab

[:space:]

Whitespace

[:cntrl:]

Control characters

[:graph:]

Printed characters except space

[:print:]

Printed characters including space

[:word:]

Digits, letters, and underscore

A Good Way to Read Regex

 

Break complicated patterns into pieces.

 

For example:

 

      ^\d{3}-\d{2}-\d{4}$

 

Read it from left to right:

 

      ^ Start of value

      \d{3} Three digits

      - Hyphen

      \d{2} Two digits

      - Hyphen

      \d{4} Four digits

      $ End of value

 

See Also: Program Control Instructions

 



PL/B Language Reference