On this page
1. Prepare to extract log fields with regex101 in JavaScript mode #
Open regex101 and choose JavaScript as the flavor, then Match mode. This example uses browser JavaScript named groups. The engine guide explains which flavor belongs to other application languages.
Start with an empty expression. Enter this original sample in Test String:
2026-10-09T08:15:00Z INFO docs-build completed
2026-10-09T08:17:32Z WARN asset missing
2026-10-09T08:19:05Z ERROR upload failed
These are practice records. They contain no account details and don't represent events on a real server. Each uses the same four-digit year, fixed UTC timestamp shape, uppercase severity and a nonempty message.
The task is extracting fields from that agreed shape. It won't validate the calendar date, establish that an event happened, or parse every possible server-log format.
2. Match the timestamp shape #
Enter:
^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z
Use the Flags controls to enable global (g) and multiline (m). You should see the timestamp at the beginning of all three lines highlighted.
The g flag finds successive matches. The m flag lets ^ refer to the beginning of each line. Without multiline mode, the beginning anchor applies to the input as a whole. These controls are documented in pattern and flags.
Fixed-width digit ranges make the example readable. A timestamp with an offset or fractional seconds needs a different agreed format; don't loosen this pattern just to make unrelated input light up.
3. Add named captures for all three fields #
Replace the expression with:
^(?<timestamp>[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z) (?<severity>INFO|WARN|ERROR) (?<message>[^\r\n]+)$
Keep g and m enabled. The full records should now match. Inspect the first result in Match Information:
| Named group | Expected text |
|---|---|
| timestamp | 2026-10-09T08:15:00Z |
| severity | INFO |
| message | docs-build completed |
Read Explanation to connect the tokens with the match. The capture-group guide explains full matches, named groups and absent optional groups.
The message class excludes carriage returns and line feeds. That prevents a message from swallowing the following record. Spaces between the fields are literal single spaces in this example; preserve that distinction when you adapt it.
4. Check lines that should fail #
Add these two lines to the sample:
2026-10-09T08:21:00Z DEBUG ignored
prefix 2026-10-09T08:22:00Z INFO ignored
Neither should match. DEBUG isn't one of the three listed severities, and the second line doesn't begin with the timestamp.
Also change the first message to empty text after its separating space. That line should fail because + requires at least one message character. Restore the original line when you've inspected the result.
These failures tell you what the rule rejects. A pattern that matches three expected lines but accepts arbitrary prefixes hasn't finished the same job.
5. Record checks in Unit Tests #
Select Unit Tests. Use Add unit test to record one valid line and one DEBUG line. Set Assertion target to regex. For the valid line choose does match; for DEBUG choose does not match, then select Run tests.
Both expectations should pass. Add a capture comparison for the valid record: group 2 should equal INFO, with the Comparison string containing that exact text. Named groups still have numerical positions in the order their capturing parentheses open.
The unit-test documentation gives the exact controls. It also explains that capture comparisons inspect the first match. To check all three records independently, give each a separate test case.
Keep short descriptions such as “Reject DEBUG” and “Capture first severity.” A colleague should understand why a failed case matters without reading the entire log sample.
6. Save the pattern with its engine and flags #
Copy the expression into a local text file alongside a note that it uses JavaScript, g and m. Save the invented sample and expectations there too. A bare pattern loses context when someone pastes it into a different language.
For a JavaScript regex literal, the surrounding form is:
const logPattern = /^(?<timestamp>[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z) (?<severity>INFO|WARN|ERROR) (?<message>[^\r\n]+)$/gm;
Verify the sample in the application's runtime before connecting it to actual logs. A RegExp constructor using a JavaScript string needs another escaping layer; the literal above avoids that extra layer.
Known problems and practical fixes #
Slashes can be delimiters
In regex101 issue 1147, the creator explains why a slash-delimited pattern requires an internal slash to be escaped, or a different delimiter chosen. If you add a URL field later, distinguish the slash in the data from the delimiter surrounding the expression. Escape the internal slash or choose a non-conflicting delimiter.
Python strings can add an escaping layer
A Python forum discussion explains how \b can become a backspace in an ordinary Python string. A raw string preserves regex syntax. When moving this example to Python, select the Python flavor, change named groups to (?P<name>...) and use the correct string representation.
Troubleshooting #
| Problem | Likely cause | Fix |
|---|---|---|
| Only the first record matches | Global matching disabled | Enable g |
| Only the first line is considered | Multiline matching disabled | Enable m |
| Lowercase severity fails | Example explicitly lists uppercase labels | Normalize the data or change the accepted labels deliberately |
| A log prefix prevents a match | Start anchor expects a timestamp | Include the real prefix in the pattern |
| Pattern works here but fails in code | Engine, flags or string escaping differs | Follow the runtime mismatch checklist |
| A blank message fails | Message group requires one or more characters | Keep that rule or deliberately support blank messages |
The runtime mismatch checklist covers the application-side checks.
Variations #
Add another severity
Add DEBUG to the severity alternatives only if your parser is meant to accept it. Change its negative expectation into a positive one and retain another rejected severity, such as TRACE, to test the rule.
Capture messages containing spaces
The message class already accepts spaces because it excludes only carriage returns and line feeds. A phrase such as upload failed after retry stays one captured value.
Parse JSON logs
Use a JSON parser for JSON records. A regex can find a simple marker in raw text, but it doesn't handle nested JSON, escaped quotes and structured values as reliably as the format's parser. CyberChef can help explore transformations; Regex Vis can help explain a pattern you retain.
Completion checklist #
- All three original records match.
- Each result has timestamp, severity and message groups.
- DEBUG and the prefixed line fail.
- The empty-message case behaves as intended.
- Unit tests contain both accepted and rejected examples.
- The saved pattern includes its JavaScript flavor and flags.
Next steps #
Use RegExr to study individual tokens or Regex Learn for short syntax exercises. The regex101 alternatives page covers other editors when your task needs a different presentation.



