Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Regular expressions with grep

After this lesson: I can write a regular expression and test it with grep.

55 min lesson8 commandsCompilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

One pattern, a whole class of strings

A regular expression, or regex, is a short pattern that describes a set of strings. One pattern can fit every order number, or every log line that mentions an error. The tool grep searches text with one.

Every regular expression can be run by a finite automaton, so you already know how it works. This lesson teaches you to write patterns and to see what they cannot do.

By the end of this lesson

Note

I can write a regular expression and test it with grep.

Key words

WordWhat it meansExample
Regular expressiona pattern that describes a set of strings
Literala character in a pattern that matches only itselfc
Quantifiera sign that says how many times to repeat+
Alternationa choice between patterns, written |cat|dog
Anchora sign that ties a match to the start or end of a line^
Matchto fit a pattern exactly

The cells students fill in are left blank in this preview.

A pattern is a few small pieces

Most characters in a pattern are literals and match themselves. A few signs are special.

A dot matches any one character. Square brackets match one character from a set or range. A star, plus or question mark repeats the piece before it. A bar chooses between two patterns, and the signs ^ and $ pin a match to the start and end of a line.

The pieces and what they match

PatternMeansMatchesDoes not match
c.tc, any one character, tcat, cotct, cart
[0-9]one digit7a
ab*ca, any number of b, then cac, abc, abbbcabd
ba+b then one or more aba, baaab
colou?rthe u is optionalcolor, colourcolouur
cat|dogeither wordcat, dogbird
^[A-Z]{2}[0-9]{2}$two capitals, two digits, nothing elseAB12AB123

The cells students fill in are left blank in this preview.

grep -E searches text with a pattern

The command grep -E prints every line that contains a match for the pattern. The -E switch turns on the full set of signs above.

The Runs below pipe a few lines from printf into grep, so you can see which lines survive. Without ^ and $, a match can be anywhere in the line.

A dot matches one character

Command
printf 'cat\ncot\ncut\ncart\n' | grep -E 'c.t'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A question mark makes a letter optional

Command
printf 'colour\ncolor\ncolr\n' | grep -E 'colou?r'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Anchors and a plus for a code

Command
printf 'A12\nB7\nC123\nD\n' | grep -E '^[A-Z][0-9]+$'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Exactly two capitals and two digits

Command
printf 'AB12\nAB1\nA123\nXY99\n' | grep -E '^[A-Z]{2}[0-9]{2}$'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A dot is not a full stop

In a pattern a dot means any one character. To match a real full stop you write a backslash before it.

The first Run below uses an unescaped dot, and the second escapes it. Compare which lines come back.

An unescaped dot matches anything

Command
printf 'report.txt\nreport_txt\nreportatxt\n' | grep -E 'report.txt'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A backslash makes the dot literal

Command
printf 'report.txt\nreport_txt\nreportatxt\n' | grep -E 'report\.txt'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think a dot in a pattern means a full stop, like in a file name. It means any one character. Put a backslash before it when you want a real full stop, as in report\.txt.

A pattern cannot count without limit

A regular expression is a finite automaton in disguise, so it has finite memory. It can say "some a, then some b". It cannot say "as many a as b".

To compare the two counts you must remember the number of a, and that number has no upper limit. The next Run shows a pattern accepting lines that are not equal.

It cannot tell aab from aabb

Command
printf 'aabb\naab\nabbb\n' | grep -E '^a+b+$'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

The lab lexer's rules are patterns

Command
grep -c "^\[" ~/compiler/calc.l

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Walking a pattern by hand

Code: python
# Walk a pattern and a text together, one place at a time.
# '#' means one digit, '@' means one letter, anything else must match itself.
pattern = "##-@"
text = "42-x"
ok = len(pattern) == len(text)
i = 0
while ok and i < len(pattern):
    p = pattern[i]
    ch = text[i]
    if p == "#":
        ok = ch.isdigit()
    elif p == "@":
        ok = ch.isalpha()
    else:
        ok = ch == p
    i = i + 1
print(ok)
# Change text to "4x-2" and run again.

About this lab and its source: Compilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.