Turn the requirement into expected passes and failures
Test a regex by writing down which complete strings must match and which must fail before tuning the pattern. A few convenient matches are not a specification; the negative cases define where the rule must stop.
Suppose a warehouse form accepts a stock code made of three uppercase ASCII letters, a hyphen, and four digits. The requirement can be represented by ^[A-Z]{3}-\d{4}$, but the expression is only a candidate until examples challenge it. Start with a small set whose expected result is unambiguous.
Positive cases might include:
PRD-0001, the lowest ordinary padded value in the sample.LAB-4820, a different prefix and a middle-range number.BOX-9999, an upper boundary for the four-digit portion.
Negative cases should fail for different reasons:
prd-0001uses lowercase letters.PRD0001is missing the hyphen.PRD-001has only three digits.PRD-00012has five digits.XPRD-0001contains an extra leading character.PRD-0001 archivedcontains trailing text.
This is not about finding a pattern that accepts the three good samples. It is about finding the smallest rule that produces the expected result for every named case. Keep the requirement beside the cases so a later change, such as allowing lowercase input, is a deliberate product decision rather than an accidental regex edit.
Run the exact pattern and flags in the Regex Tester
Enter the candidate expression, its intended flags, and the case set in the Regex Tester. The page uses the browser's JavaScript RegExp behavior, highlights matched text, lists match positions, and reports a compilation error when the pattern or flag string is invalid.
For validation of one complete value, test each case separately or place one value per line and design the anchors for multiline input deliberately. The m flag changes how ^ and $ behave around line boundaries. Without m, those anchors refer to the start and end of the full test text; with it, they can refer to individual lines. A pattern that appears broken may simply be receiving a different text shape than the field in the real application.
The g flag changes the tester from reporting the first match to collecting repeated matches. That is useful for search tasks, but it is usually not the deciding option for a single-field pass/fail rule. Do not add g merely to make more highlights appear. Use the same flags that the consuming application will use, and record them next to the pattern.
The visible match position is part of the evidence. If PRD-0001 is highlighted inside XPRD-0001, the inner text may look right while the full value is wrong. That points to a missing boundary or anchor. Read the characters immediately before and after each highlight instead of treating any highlight as a pass.
Add one negative case for every part of the rule
A useful negative set isolates one broken condition at a time. If several conditions fail in one sample, a pass or failure does not reveal which part of the pattern needs attention.
For the stock-code rule, challenge the letter count, character case, separator, digit count, leading boundary, trailing boundary, and blank input independently. Then add realistic input hazards such as a space copied from a spreadsheet, a line break, a non-ASCII dash, or a full-width digit. These cases help the team decide whether input should be normalized before validation or rejected with a clear message.
Avoid silently expanding the regex whenever a new example fails. A user entering PRD–0001 with an en dash may need a friendly correction rather than a pattern that accepts several visually similar punctuation characters. The right response depends on the field's contract. Record that decision outside the regex so reviewers can understand why the case passes or fails.
Blank strings deserve an explicit expectation. * and ? can allow zero occurrences, and an alternation can contain an empty branch. If a blank value unexpectedly matches, reduce the expression and inspect each optional group. The tester can show the result, but it cannot decide whether a blank stock code is valid for the business process.
Diagnose false positives and false negatives separately
A false positive means the pattern accepted a value that the requirement rejects; a false negative means it rejected a valid value. Fixing one class can create the other, so rerun the complete set after every pattern change.
When a negative case passes, inspect these common causes:
- Missing
^or$anchors allow a valid-looking substring inside a longer value. - A broad class such as
.or\waccepts characters beyond the stated alphabet. - A quantifier such as
+accepts an unlimited count when the format needs an exact length. - An optional group makes a required separator or segment disappear.
When a positive case fails, check a different set of questions:
- Is the test text carrying a trailing space or hidden line break?
- Does the real requirement include Unicode letters or only ASCII?
- Are the flags identical to the application configuration?
- Was a literal symbol escaped for the regex itself and then escaped again for a JSON or programming-language string?
That last distinction matters. The pattern entered in a browser field is not always written the same way as a string literal in source code. If test fixtures are stored in JSON, use the JSON Formatter to confirm that the JSON itself parses, then check the decoded pattern in the actual runtime. Formatting JSON does not prove that the regex is correct or that backslashes survived every application layer.
Keep the case list as a reviewable artifact
Save the pattern, flags, example, and expected outcome together in the project's normal test system. A browser check is a fast design aid, while automated tests in the consuming code protect the rule when dependencies, input handling, or requirements change.
One lightweight review format is a plain-text list containing a case ID, the input, and PASS or FAIL. After editing the rule, generate the actual outcomes in the application and compare that list with the expected list using the Text Diff tool. The comparison page only evaluates text that you paste; it does not execute the regex, open a repository, or certify the application result.
Give boundary cases stable names such as missing-hyphen or extra-leading-character. Names make a future failure easier to discuss than a long unlabeled block of sample data. When the requirement changes, update the named expectation first, obtain review, and then edit the pattern.
Do not paste customer records, credentials, access tokens, or an entire production export into a test page. Replace sensitive values with synthetic examples that preserve only the relevant shape. The final verification belongs in the exact regex engine and input path used by the product, because JavaScript syntax and flags can differ from .NET, Python, PCRE, database, and command-line engines.
Check the application behavior, not only the regex result
A correct match result is only one part of a usable validation flow. The application also needs to trim or preserve input consistently, show an actionable error, handle an empty field, and avoid changing the saved value unexpectedly.
Run the named cases through the real form, API, or parser after the browser pattern behaves as expected. Confirm both the acceptance decision and the value that is stored. If the application normalizes lowercase to uppercase, test that transformation as a separate rule. If it rejects lowercase, verify that the message tells the user what to enter.
The Regex Tester does not modify files, replace text, deploy code, or prove that a downstream system shares JavaScript regex semantics. Its result is a focused observation about the pattern, flags, and text currently entered. Preserve the case set and rerun it where the rule will actually execute.
Frequently asked questions
How many positive regex examples are enough?
Use at least one ordinary valid value and valid boundary values for every constrained segment. The number is less useful than coverage: each allowed variation should have a named example.
Why do I need negative examples if the valid format is simple?
Negative examples expose missing anchors, broad character classes, optional required parts, and length mistakes. They define what the regex must refuse, which a list of valid samples cannot do.
Should I put the global flag on a validation regex?
Usually a single-field validation checks one complete value and does not need g. Use the flags required by the real application, and test repeated matching separately when the task is searching through text.
Can the browser tester prove the pattern works in Python or .NET?
No. This page uses JavaScript regular expressions. Re-run the same named cases in the exact engine, language version, and input path used by the application.
What should I save with the pattern?
Save the pattern text, flags, engine, named inputs, expected pass or fail result, and the requirement each case represents. That record makes later changes reviewable instead of relying on memory.