Choosing Between PARSE and RXREGEX for Log Parsing in Rexx
A decision guide for Rexx log parsing: when the built-in PARSE instruction is enough, when the RXREGEX library earns its dependency, and a script that validates both against the same line.
30 Sept 2025, 11:17 UTC

The decision
You need to pull a timestamp, a severity level, and a message out of each line of a log file, and you need to do it in Rexx. The two realistic options are the built-in PARSE instruction and the external RXREGEX library, which wraps a PCRE-style regular expression engine. The constraints that matter here:
- The script should run on ooRexx 5.0 or later.
- Third-party packages are allowed but not guaranteed on every machine the script may reach.
- The people maintaining this know basic Rexx, not necessarily regex.
The short answer: start with PARSE. Move to RXREGEX only when the log format grows optional fields, quoted strings, or variable structure that makes positional parsing fragile.
Comparing the supported options
| Criterion | PARSE (built-in) | RXREGEX (library) |
|---|---|---|
| Dependencies | None; part of the language | External library must be installed and loadable |
| Pattern power | Literal delimiters and positional templates only | Full regular expressions (character classes, alternation, optional groups) |
| Performance | Fast; typically sub-millisecond per line | Slower; library load plus regex compilation per call |
| Readability for simple formats | Excellent — one line does the job | Overkill; pattern obscures intent |
| Readability for complex formats | Degrades into chains of PARSE and string functions | One anchored pattern expresses the whole structure |
| Failure mode if missing | Cannot fail — always present | Syntax error at the ADDRESS RXREGEX statement |
Trade-offs in practice
Portability. A script using only PARSE runs on any Rexx interpreter with zero install footprint. If your log parser ships to systems you do not control — customer machines, z/OS and ooRexx mixed environments, minimal containers — this is decisive.
Maintainability. For a fixed format like 2026-10-13 06:29:23 INFO User logged in, PARSE is genuinely clearer. But logs evolve. Once you have optional request IDs, quoted messages containing spaces, or severity levels of varying width, a PARSE-based solution becomes a stack of PARSE VAR, POS(), and SUBSTR() calls that each new maintainer has to reverse-engineer. A single anchored regex documents the expected shape of a line in one expression.
Correctness risk. Regexes introduce their own bugs: unanchored patterns matching the wrong part of a line, greedy quantifiers swallowing delimiters. If you switch, test against representative real log data, not just one hand-written sample line.
Deployment risk. If RXREGEX is absent, the script dies at the ADDRESS RXREGEX statement. Either bundle the library with the application or check availability at startup and fall back to PARSE.
Concrete implementation and validation
The following ooRexx script parses one line both ways, compares the results, and times each approach using the TIME built-in with the elapsed ('E') option. Run it from a command prompt with rexx logparse.rex; no special permissions are needed. It requires RXREGEX to be installed for the second half — comment that block out to test the PARSE path alone.
/* logparse.rex — compare PARSE vs RXREGEX on one log line */
line = '2026-10-13 06:29:23 INFO User logged in'
/* --- Approach 1: built-in PARSE --- */
t0 = TIME('R')
PARSE VAR line date time severity message
ts1 = date time
elapsed1 = TIME('E')
/* --- Approach 2: RXREGEX --- */
t0 = TIME('R')
CALL RXFUNCADD 'RxRegEx', 'rxregex', 'RxRegEx'
pat = '^(\S+ \S+) (\S+) (.*)$'
IF RxRegEx(pat, line, 'm.') > 0 THEN DO
ts2 = m.1; severity2 = m.2; message2 = m.3
END
elapsed2 = TIME('E')
/* --- Validation --- */
SAY 'PARSE :' ts1 '|' severity '|' message
SAY 'RXREGEX :' ts2 '|' severity2 '|' message2
IF ts1 == ts2 & severity == severity2 & message == message2 THEN
SAY 'MATCH: both methods agree'
ELSE
SAY 'MISMATCH: investigate before deploying'
SAY 'PARSE elapsed (s):' elapsed1
SAY 'RXREGEX elapsed (s):' elapsed2
Exact function names and the capture-stem convention vary between RXREGEX distributions, so check the documentation for the build you install and adjust the RXFUNCADD registration and call signature accordingly — this is the part most likely to need local adaptation.
How to check the result
- Run the script against the sample line. Both extraction blocks must print identical timestamp, severity, and message values; the script flags a mismatch itself.
- Compare the elapsed times. Expect PARSE to complete in well under a millisecond per line and RXREGEX to take measurably longer, especially on the first call while the library loads. For a one-off comparison per line this is noise; for a million-line batch it is not.
- Feed the script real log lines, including malformed ones. Confirm the regex either matches correctly or fails to match at all — a partial, wrong match is the dangerous outcome.
- Test on a machine without RXREGEX installed. The PARSE-only path must still work; the script should degrade gracefully rather than abort with a syntax error.
Limitations
Timing numbers from TIME('E') are coarse and machine-dependent; treat them as directional, not benchmarks. The regex shown assumes single-space-separated fields with no leading whitespace — production logs with multi-line stack traces or embedded timestamps in the message body need a more careful pattern and per-line anchoring. Finally, RXREGEX packaging differs across platforms, so the install step is environment-specific and out of scope for the script itself.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.