What a pattern is
You already search PDFs by typing words. A pattern lets you search for a shape instead of exact words.
Suppose a 400-page standard says “see page 12”, “see page 147” and “see page 9”. There is no single piece of text you can type that finds all three — the number is different every time. But they all share a shape: the words see page, then a space, then some digits. Written as a pattern, that shape is:
see page \d+
\d means “any digit”. + means “one or more of
those”. Everything else is ordinary text that matches itself. That is the whole idea;
the rest of this page is just more shapes.
Tip
When not to use a pattern. If you are looking for the literal words Confidential Draft and nothing else, just type them and leave Use regular expressions switched off. Patterns are for when the thing you want varies — a page number that changes, a date in any month, a section number of unknown depth.
Before writing a pattern, it helps to answer three questions:
- What varies? That part becomes
\d+,[A-Z]or similar. - What stays the same? That part you type literally.
- Which part do I actually want to keep? That part goes in brackets — see Capture groups. This is the question people forget, and it is the one that matters most in TOC Builder.
Building your first pattern
Here is how one of the patterns supplied with TOC Builder was built up, one step at a time. The goal: find every cross-reference of the form “see page 47” in a long specification.
-
see page 47
Works once. Useless — it only finds page 47. -
see page \d+
Now any page number matches. But it fails on “see page 47” with two spaces, and on “See page 47” with a capital S. -
see\s+page\s+\d+
\sis any space, tab or line break and+means one or more, so any amount of spacing works. This matters specifically in PDFs: text pulled out of a PDF often has irregular spacing where the original was justified, so a single typed space frequently misses matches that look fine on screen. -
see\s+page\s+(\d+)
The brackets mark the part you want to keep. The page number is now capture group 1.
That last line is exactly the supplied library entry Page references › see page N. The library is not magic — you have just derived one of its 128 entries.
Literal text, and the characters that are not literal
Almost everything you type matches itself. These twelve characters do not — they have a special meaning:
. ^ $ * + ?
( ) [ ] { }
| \
To match one of them for real, put a backslash in front of it.
The commonest mistake
. matches any single character, not a full stop.
Fig.12 finds “Fig.12” — and also “Fig512”,
“Fig 12” and “FigX12”.
Fig\.12 finds only “Fig.12”.
This bites hardest with section numbers: 3.4.5 matches
“3.4.5” but also “31465”.
Matching a kind of character
| Write | Means | In a document |
|---|---|---|
\d | any digit | the 7 in “Figure 7” |
\w | letter, digit or underscore | any character of “Appendix” |
\s | space, tab or line break | the gap in “see page” |
\D \W \S | the opposite of each | |
[A-Z] | one capital letter | the A in “Appendix A” |
[0-9] | same as \d | |
[IVXLCDM] | one Roman numeral letter | the X in “Part XIV” |
[^0-9] | anything that is not a digit | ^ inside brackets means “not” |
[-–] | a hyphen or an en dash | “12-18” and “12–18” |
Tip
That last row earns its place. Documents produced from Word or InDesign use en dashes in
page ranges, so a pattern written with a plain hyphen silently misses half the document.
The supplied entry Page references › pages N–M uses
[-–] for exactly this reason.
How many
| Write | Means | Example | Finds |
|---|---|---|---|
* | zero or more | Fig\.\s*12 | Fig.12 and Fig. 12 |
+ | one or more | \d+ | 3, 47, 1024 |
? | optional — none or one | Figs? | Fig and Figs |
{4} | exactly four | \d{4} | 2026 |
{2,4} | between two and four | [A-Z]{2,4}-\d+ | ABC-1234 |
{2,} | two or more | \d{2,} | 47, 1024 |
A repeat always applies to the one thing immediately before it. In
Figs? the ? applies to the s alone, not to the whole
word — which is why it finds both “Fig” and “Figs”.
Why your pattern matched far too much
Suppose a line reads:
Approved by "J. Smith" and "R. Patel" on 4 March
You want the quoted names, so you write "(.+)". What you get back is
J. Smith" and "R. Patel — one huge match. .+ is
greedy: it takes as much as it possibly can and only gives back what it must.
Adding a question mark after the repeat makes it take as little as possible instead.
"(.+?)" gives you J. Smith, then R. Patel.
Rule of thumb
The moment you write .+ or .* between two markers, write
.+? or .*? instead.
Where on the page
| Write | Means | Example |
|---|---|---|
^ | start of the text | ^INTENTIONALLY BLANK$ |
$ | end of the text | Page \d+$ |
\b | the edge of a word | \bTable\s+(\d+) finds “Table 3”, not “Turntable 3” |
\b is what makes the supplied entry Page references › p N
(\bp\.?\s*(\d+)\b) skip the “p.” inside “Corp.”
Warning
In most features ^ and $ mean the start and end of the
whole extracted text of the page, not of each line. Only
Generate Links from Rules offers a per-line option (its m
checkbox). This is why the supplied Notes and Lists
patterns, which begin with ^, behave differently depending on which dialog
you paste them into.
Either / or, and grouping
| means “or”: Figure|Table finds whichever appears.
Brackets group things so a repeat or an “or” applies to all of them at once.
There are two kinds of bracket. ( ) groups and keeps what is inside.
(?: ) groups without keeping. The supplied year pattern uses both:
\b((?:19|20)\d{2})\b
The outer brackets keep the whole year. The inner (?:19|20) only groups the
either/or, so that the year has to start 19 or 20 — without it, 19|20\d{2}
would mean “the text 19, or 20 followed by two digits”, which is not what anyone
wants.
Capture groups — the part you keep
Brackets do two jobs at once: they group things together, and they keep what is inside them.
Invoice #(\d+) matches the whole of “Invoice #4471”, but capture
group 1 holds just 4471.
This is not decoration. In several TOC Builder features the captured part is the answer:
| Feature | What it does with your capture |
|---|---|
| Split by Pattern Change | Uses capture group 1 as the split key. Consecutive pages with the same captured value go into the same file. With no brackets at all, the whole match is used instead. |
| Generate Links from Rules | You put \1 into the action fields to build the link target out of the
captured text. |
| Search and Replace | You type $1 in the Replace field to keep part of what you found. |
| Split output file names | {match:PATTERN} puts the first match into the output file name. |
A worked example
A statement run has “Invoice 4471” on pages 1–3, “Invoice 4472” on pages 4–9 and “Invoice 4473” on page 10.
Split by Pattern Change with Invoice\s+(\d+) gives three files, split exactly
where the number changes.
The same job with Invoice\s+\d+ — no brackets — gives you
one file. Every page matches the same whole-match shape, so as far as the
feature is concerned nothing ever “changes”. If a split produces a single file
when you expected several, a missing pair of brackets is almost always why.
Note
\1 means two different things depending on where you type it.
Inside a pattern, \1 means “the same text that group 1 already
matched” — (\w+)\s+\1 finds a doubled word like “the
the”.
Inside a Generate Links value field, \1 means “insert what
group 1 captured”. See Putting captures back.
Putting captures back
Warning
There are two different replacement notations in TOC Builder, and they are not interchangeable.
| Feature | Notation |
|---|---|
| Search and Replace (bookmark titles) | $1…$9, $&, $$ |
| Search and Replace URLs in Bookmarks | $1… |
| Search and Replace URLs in Links | $1… |
| Generate Links from Rules | \0…\9 only. $1 is inserted as the literal text “$1”. |
A worked pair. Bookmarks read “Chapter 4 — Installation” and you want “4. Installation”:
- In Search and Replace: find
Chapter (\d+) — (.+), replace with$1. $2. - The same rule in Generate Links from Rules would be written
\1. \2.
Two more that only apply to Search and Replace: $& inserts the whole match,
and $$ inserts a real dollar sign. To turn 1,234.56 into
$1,234.56 you would type $$$&.
Capitals and matching
Warning
(?i) does not work in TOC Builder. You may have seen it
recommended elsewhere — it is common in other programs — but a pattern
beginning (?i) is rejected here as invalid.
Capitals are controlled per feature; see the table below. Where a feature gives you no
option, put the choice in the pattern itself: [Ss]ection\s+(\d+) matches both
“Section 4” and “section 4”.
Behaviour is not uniform across the product, and this catches people out. The same saved pattern can match differently depending on which dialog uses it:
| Feature | Capitals |
|---|---|
| Search and Replace (bookmarks) | Match case checkbox; off by default, so capitals are ignored |
| Search and Replace URLs (bookmarks and links) | Match case checkbox |
| Find / Edit Bookmark Properties | Match case checkbox |
| Delete Pages by Text Search | Match case checkbox |
| Bookmarks from Text Patterns | Match case checkbox, per rule |
| Highlight Text Patterns | Match case, per pattern |
| Generate Links from Rules | i checkbox (plus m, g, x, u) |
| Extract by Text Pattern | Always ignores capitals. No option. |
| Split by Text Pattern | Always ignores capitals. |
| Split by Pattern Change | Always ignores capitals. |
| Delete Text Highlights | Always matches capitals exactly. No option. |
Note
A library entry carries no capitals setting. The library stores the
group, name, pattern, description and example — not how it should be matched. If a
pattern must always ignore capitals, build that into the pattern with a character class
such as [Ff]igure rather than relying on whichever dialog you happen to use it in.
Matching a real full stop, bracket or backslash
Put a backslash in front of any special character to match it literally:
\. \( \) \[ \]
\$ \? \+ \* \\
The supplied equation pattern shows both meanings of a bracket in one line:
\bEq\.?\s*\((\d+)\)
The \( and \) match the real brackets printed around the number;
the plain ( and ) in the middle do the capturing. The
\. is a real full stop, and the ? after it makes that full stop
optional, so both “Eq. (3)” and “Eq (3)” match.
A Windows path needs each backslash written twice:
([A-Za-z]:\\[A-Za-z0-9_\-\\\. ]+) finds C:\Specs\report.pdf.
Where patterns are used
Patterns are matched against the text extracted from the page, not against what you see on screen. That difference explains most “why did this not match?” puzzles: extracted text can carry odd spacing, and words split across a line break may not join up the way they look.
Features that accept a pattern:
- Bookmarks from Text Patterns — page text
- Search and Replace — bookmark titles
- Find / Edit Bookmark Properties — bookmark titles
- Split by Pattern Change — page text, keyed on group 1
- Split by Text Pattern — page text
- Extract by Text Pattern — page text
- Delete Pages by Text Search — page text
- Highlight Text Patterns — page text
- Delete Text Highlights — annotation text
- Search and Replace URLs in Links — link URLs
- Search and Replace URLs in Bookmarks — bookmark URLs
The patterns supplied with TOC Builder
TOC Builder ships with 128 ready-made patterns in 22 groups, available from the Regular Expression Library. Each one now carries a plain-English description of what it finds and an example of text it matches.
The groups are: Basics, Page references, Page labels, Sections, Figures, Tables, Equations, Boxes, Listings, Appendices, Cross-refs, URLs/Files/IDs, Legal/Standards, Dates/Times, Numbers, Codes, Citations, Notes, Lists, Addresses/Phones, Cross-document and General.
Tip
Look in the library before writing anything. One of the 128 is probably close to what you need, and editing a working pattern is far easier than writing one from scratch. Start with the Basics group if the syntax is new to you — those entries exist to be read, not just used.
Testing a pattern safely
- Use the Try it box in the Regular Expression Library. Select a pattern and type sample text; it shows every match and the value of each capture group as you type.
- Run it on a five-page range first, not the whole document.
- Check the number of matches, not just that there are some. Too many matches is the common failure, not zero.
- Save the file first. Most of these operations cannot be undone item by item.
- When a pattern works, save it into the library with a name and description that say what it finds — so the next person does not have to work it out again.
Ten things that go wrong
| Symptom | Cause | Fix |
|---|---|---|
| Matched far too much | .+ is greedy | Use .+? |
| Matched “Fig512” | . means any character | Use \. |
| Found nothing, pattern looks right | Extracted text has irregular spacing | Use \s+ instead of a typed space |
| Missed half the page ranges | Document uses en dashes | Use [-–] |
| Split produced one file | No capture group | Add brackets around the varying part |
| Replacement inserted the literal “$1” | Wrong notation for that dialog | Use \1 in Generate Links |
| “Invalid regular expression” | Unbalanced bracket, or an (?i) prefix | Read the message — it names the character position |
| Works in one dialog, not another | Different capitals handling | See Capitals and matching |
| Matched inside longer words | Missing \b | Wrap the word in \b…\b |
^ did not work | It means start of the whole page text | Use a different anchor, or Generate Links with m |
Five jobs from real documents
| Goal | Pattern | Feature |
|---|---|---|
| Bookmark every numbered section | \bSection\s+((?:\d+\.)+\d+)\b | Bookmarks from Text Patterns |
| Split a statement run by invoice number | Invoice\s+(\d+) | Split by Pattern Change |
| Renumber “Chapter 4 — Installation” to “4. Installation” | find Chapter (\d+) — (.+), replace $1. $2 | Search and Replace |
| Extract every page citing a standard | \b(ISO\s+\d{4,5}-\d+)\b | Extract by Text Pattern |
| Turn “see page 47” into working links | see\s+page\s+(\d+) with \1 as the target | Generate Links from Rules |
Learning more
Regular expressions are not a Mapsoft invention. They are a standard notation used by dozens of programs, so anything you learn about them transfers — and there is a great deal of good free material. These are the sites we recommend. They all open in a new tab.
- Regular-Expressions.info — Quick Start Start here if you want to learn properly. The clearest long-form tutorial on the web, and written for people who are not programmers. Read the Quick Start, then follow the tutorial links down the left-hand side.
- MDN — Regular expression syntax cheat sheet A reliable place to look up a single symbol. MDN documents JavaScript’s regular expressions, which are the same family TOC Builder uses, so its tables apply here almost exactly.
- regex101 Test a pattern before you run it on a 400-page document. Paste a pattern and some sample text and it highlights every match and explains the pattern piece by piece. Set the flavour first — see the note below.
- RegExr A simpler, friendlier tester. Hover over any part of a pattern and it tells you what that part does. It uses the JavaScript flavour by default, which is the right one here.
- cppreference — Modified ECMA-262 grammar Technical, and only for settling an argument: this is the exact specification of the pattern syntax TOC Builder accepts.
Set the flavour before you test
Regular expressions come in slightly different dialects, usually called flavours. TOC Builder uses the ECMAScript flavour — the same one as JavaScript. On regex101, choose ECMAScript (JavaScript) in the FLAVOR list on the left before you start; it opens in PCRE2 mode, which accepts things TOC Builder will reject.
Even in ECMAScript mode, a few things those sites allow are not available here:
look-behind (?<=…), named groups
(?<name>…), Unicode property escapes \p{…},
and inline switches such as (?i). Look-ahead
— (?=…) and (?!…) — is
supported. See Not supported.
Note
These are third-party websites. They are not operated by Mapsoft, and we cannot control their content or availability. We list them because we find them useful, not as an endorsement.