SheepDev

Text and regular expressions

Check what your regular expression actually matches

Tools to use

A regex can feel finished as soon as it finds one desired value. The harder failures are silently capturing a lookalike or dropping an unusual line. Start with a short target and explicit expected results, then add conditions one at a time rather than writing a complicated expression immediately.

Use fictional order IDs. The tester uses JavaScript regex syntax with separate pattern and flag fields. Before working with sensitive logs, use this small example to distinguish the full match, captured groups, and replaced text.

Include two wanted and two unwanted examples

Target text
order-104
order-205
preorder-306
order-407x
First pattern, without surrounding slashes
order-([0-9]+)

With gm flags, this pattern finds four matches: preorder-306 contains order-306, and order-407x starts with order-407. Merely including the two desired results is insufficient. The missing requirement is that an entire line, not a substring, must be an order ID.

Anchor the start and end of each line

Whole-line pattern, flags gm
^order-([0-9]+)$

Adding ^ and $ with gm leaves order-104 and order-205. The m flag makes those anchors operate at line boundaries. With g but without m, the four-line target does not match as one complete order ID. Global matching and multiline anchors serve different purposes.

SheepDev currently adds g internally to enumerate matches; removing it does not turn this screen into a first-match-only test. If destination code handles only the first match, test that invocation separately. The same pattern can behave differently with another API or flag set.

Separate the full match from captured digits

The parentheses in ([0-9]+) capture the digits: the full match is order-104, while group 1 is 104. This generalizes to other IDs instead of hardcoding one value. Because + requires at least one digit, order- alone fails. Whether an empty digit sequence should be allowed is a separate specification decision.

This pattern does not accept full-width digits, signs, or grouping separators. If order-012 must be valid, specify that and add a test. Nor should captured 001 automatically become numeric 1: preserve identifier semantics in downstream processing.

Replacement leaves unmatched lines intact

Replacement string
ID:$1
Replacement with the anchored pattern and gm
ID:104
ID:205
preorder-306
order-407x

$1 inserts the first captured group. Only the two matched lines become ID:104 and ID:205; the other lines remain. Decide whether you want captured values alone or a modified copy of the source. Mistaking replacement output for an extraction list makes intentionally unmatched lines look like unexpected results.

Adding capturing parentheses can change group numbering. After editing the pattern, recheck the replacement rather than assuming its references still mean the same thing. Replacement strings have special syntax too. Test a matching line, a nonmatching line, and a nearly empty line before applying the expression broadly.

A pattern field is not a source-code string literal

Enter the pattern body here, without surrounding slashes or appended gm; flags have their own field. Source-code string literals may require another layer of backslash escaping. If a working pattern fails after being pasted into code, distinguish the regex from the string syntax containing it.

Other languages and databases may use different regex dialects. Success here does not guarantee portability. Check destination flags, Unicode behavior, syntax support, and replacement-group references, then rerun the same positive and negative examples there.

A timeout is not 'no match'

Some patterns become dramatically more expensive with slightly longer inputs. The tool runs them in a worker with an approximately one-second cutoff. A timeout means evaluation did not finish, not that nothing matched. Test longer failing inputs as well as short successful ones when assessing behavior.

Input and pattern sizes are bounded, and the displayed match list stops at 5,000. A full list is not proof of the total match count. Production validation or log aggregation needs its own limits and failure policy. Copying the pattern does not copy this tool's timeout protection.

Add near misses, not just successful examples

A pattern extracting one order number is not finished merely because one example works. Add a prefix, one fewer digit and a trailing character. Partial matches may be correct for extraction but wrong for validating the entire line. Inspect highlighted ranges, not only match counts. The substring you want to extract and the whole input you want to validate are different scopes.

Digit syntax has assumptions too. JavaScript's ordinary \d does not automatically treat full-width 123 as ASCII digits. Whether to normalize input or permit another character set is a data rule. Likewise, a case-insensitive flag does not establish that an identifier is inherently case-insensitive. Match the expression to the allowed-input definition instead of relaxing rules merely to make examples pass.

Carry both positive and negative examples into application tests. Moving a JavaScript expression to another engine requires checking flags, groups, newline behavior and replacement syntax. Finishing here within a second does not guarantee speed for every input length or runtime. Test longer nonmatching inputs too, and never turn a timeout into an accepted empty extraction.

Sources

Tools to use

Guides →