# How I test a regex before putting it into code

A beginner-friendly guide to testing regular expressions with sample text, flags, capture groups, anchors, and replacement previews before using them in code.

- Date: 2026-09-27
- URL: https://ilham.dev/posts/how-to-test-regex-before-using-it/
- Markdown: https://ilham.dev/posts/how-to-test-regex-before-using-it/index.md
- Tags: regex, text, developer-tools, tools
- Reading time: 4 min


Regex is powerful, but it is also easy to get almost right. “Almost right” is the
problem. A regex can match too much, too little, or the right thing in your test but
the wrong thing in production.

That is why I test patterns with the [Regex Tester](/tools/regex-tester/) before I
put them into code. If I need replacement, I use the
[Regex Replace Tester](/tools/regex-replace-tester/) too.

## The simple idea

A regex is a pattern for matching text.

Example:

```regex
error
```

This matches the word `error`.

A slightly more flexible pattern:

```regex
errors?
```

This matches:

```text
error
errors
```

because `s?` means “the `s` is optional”.

## Step 1: start with real sample text

Do not test a regex only on perfect input. Paste realistic examples into the tester.

For example, if I am matching log lines, I paste several real-looking lines:

```text
2026-09-27 10:00:01 INFO server started
2026-09-27 10:00:03 ERROR database connection failed
2026-09-27 10:00:04 WARN retrying connection
```

Then I build the pattern against that sample.

Good sample text should include:

- lines that should match;
- lines that should not match;
- edge cases;
- messy input if real input is messy.

## Step 2: start simple

I do not start with a clever regex. I start with the smallest useful pattern.

```regex
ERROR
```

Then I add detail:

```regex
^\d{4}-\d{2}-\d{2} .* ERROR .*$
```

Plain meaning:

- start at the beginning of the line;
- match a date like `2026-09-27`;
- match anything after it;
- require `ERROR`;
- match the rest of the line.

Building in steps makes it easier to see where the pattern breaks.

## Step 3: understand anchors

Anchors do not match characters. They match positions.

Common anchors:

```regex
^
```

means start of line or string.

```regex
$
```

means end of line or string.

Example:

```regex
^ERROR
```

matches lines that start with `ERROR`.

It does not match:

```text
2026-09-27 ERROR failed
```

because `ERROR` is not at the start.

## Step 4: use character classes carefully

A character class matches one character from a set.

```regex
[abc]
```

matches `a`, `b`, or `c`.

Common shortcuts:

```regex
\d
```

matches a digit.

```regex
\w
```

matches a word character.

```regex
\s
```

matches whitespace.

A date pattern might use:

```regex
\d{4}-\d{2}-\d{2}
```

Plain meaning:

> four digits, dash, two digits, dash, two digits.

## Step 5: watch greedy matching

This pattern is greedy:

```regex
<.*>
```

Given:

```html
<b>one</b><i>two</i>
```

it may match from the first `<` to the last `>`:

```html
<b>one</b><i>two</i>
```

not just:

```html
<b>
```

A less greedy version uses `?`:

```regex
<.*?>
```

Regex and HTML are a dangerous mix for real parsing, but this example shows why
greediness matters.

## Step 6: use capture groups intentionally

Parentheses capture parts of a match.

Example:

```regex
user_id=(\d+)
```

Given:

```text
user_id=123
```

The whole match is:

```text
user_id=123
```

The captured group is:

```text
123
```

Capture groups are useful when code needs only part of the match.

## Step 7: test replacement separately

Replacement has its own risks. A pattern can match correctly but replace badly.

Suppose I want to turn:

```text
Doe, Jane
```

into:

```text
Jane Doe
```

Pattern:

```regex
(\w+),\s*(\w+)
```

Replacement:

```text
$2 $1
```

Use [Regex Replace Tester](/tools/regex-replace-tester/) to preview this before
running it across real text.

## Step 8: check flags

Flags change regex behaviour.

Common flags:

- `i`: case-insensitive;
- `g`: global, match more than once;
- `m`: multiline anchors;
- `s`: dot also matches newlines, depending on the engine.

The same pattern can behave differently with different flags. Always test with the
same flags your code will use.

## Step 9: know your regex engine

JavaScript, Python, PostgreSQL, nginx, and grep do not all support exactly the same
regex features.

A pattern that works in one place may fail in another.

Before using advanced features, check whether your target environment supports them.
For simple patterns, this rarely matters. For lookbehind, named groups, or Unicode
features, it can matter a lot.

## My regex checklist

Before using a regex in code, I check:

1. Did I test it with realistic sample text?
2. Did I include examples that should not match?
3. Is the pattern too broad?
4. Do anchors behave the way I expect?
5. Are greedy parts safe?
6. Are capture groups intentional?
7. Are flags correct?
8. If replacing text, did I preview the replacement?
9. Does my target environment support this regex syntax?

Regex is useful when the pattern is clear. The tester helps make that clarity visible
before the pattern touches real data.
