bokamba / logforge /

osregex lab

100% client-side

A faithful, client-side tester for Wazuh's regex dialects. OS_Regex (<regex>) and OS_Match (<match>) are not PCRE — a bare . is a literal dot, \. matches any character, and +/* only follow a backslash-expression. Paste a pattern, evaluate it against your lines, and check captures before you deploy the decoder.

pattern

sample ▾

test strings

one line evaluated per row

results

enter a pattern and some test lines — matches appear here

PCRE → OS_Regex assist

warns on every construct with no faithful equivalent
OS_Regex translation

translation and warnings appear here

Wazuh OS_Regex vs PCRE

An os_regex cheat sheet: how each common regex construct behaves in Wazuh's <regex> (OS_Regex) and <match> (OS_Match) dialects compared with PCRE. The biggest surprise is the . / \. inversion — everything else follows from OS_Regex being a small, decoder-oriented engine.

construct PCRE OS_Regex / Wazuh note
. (dot) Any single character. A LITERAL dot — matches only the character ".". The #1 gotcha: meaning is INVERTED from PCRE. To match "any char" in OS_Regex use `\.`.
\. (escaped dot) A literal dot. ANY single character. Inverted from PCRE. `\.` is OS_Regex's "any char"; a bare `.` is the literal dot.
+ / * (quantifiers) Repeat the preceding token (literal, class, group) one-or-more / zero-or-more. Repeat ONLY a backslash-expression: `\w+`, `\d*` are valid; `a+`, `.+`, `)+` are pattern errors. Docs: "+ and * can only be applied to backslash expressions." `0+` is NOT valid OS_Regex.
? (optional) & {n,m} Optional token; bounded/ranged repetition. Not supported — no `?`, no `{n}`, `{n,}`, `{n,m}`. Use `+`/`*` on a backslash-expr, or expand the repetition manually / into separate decoders.
( … ) groups Grouping + capture; can contain alternation `(a|b)`. POSITIONAL capture groups (mapped to `<order>`). Alternation inside a group is a pattern error. Captures are positional, not named. `(foo|bar)` is NOT permitted inside `()`.
Named captures (?<n>…) Capture into a name you reference later. No named captures — only positional `( … )`. Translate to a plain `( … )` and map it to a field via the decoder's `<order>`.
| (alternation) OR anywhere, including inside groups. Whole-pattern OR only: `A|B|C`. Never inside `()`. Top-level alternatives are tried left-to-right; the first match wins.
Lookaround (?=)(?!)(?<=)(?<!) Zero-width assertions that test without consuming. No lookaround of any kind. OS_Regex cannot assert without consuming; restructure the decoder instead.
\w (word char) [A-Za-z0-9_]. [A-Za-z0-9] plus `-`, `@`, and `_`. OS_Regex `\w` is WIDER: it also matches hyphen and at-sign (handy for usernames/hostnames).
\d \s (classes) \d = [0-9]; \s = whitespace incl. tab, \r\n\f\v. \d = [0-9]; \s = a single ASCII space (32) only. `\d` matches the same set; `\s` is narrower — it matches ONLY a space, not tab (a tab falls to `\S`).
\p (punctuation) No such shorthand (use [[:punct:]] / a class). Punctuation class: ( ) * + , - . : ; < = > ? [ ] ! " ' # $ % & | { }. OS_Regex-specific shorthand. Useful as the ONLY way to match `*` or `+` as data.
Literal ^ * + Escape them: `\^`, `\*`, `\+`. No way to match a literal `^`, `*`, or `+` directly. Docs: these cannot be matched literally. `\p` matches `*`/`+` as punctuation as a fallback.
^ $ (anchors) Line/string start & end (multiline-aware). `^` = start of text (only at pattern start); `$` = end of text (only at pattern end). Not multiline. Only meaningful at the pattern's very start / very end.
Unanchored matching Scans by default; `^` pins to start. Without `^`, OS_Regex SCANS (match may begin anywhere); with `^` it is anchored at position 0. Same intuition as PCRE — add `^` to anchor at the beginning.
<regex> vs <match> One engine (PCRE) for everything. `<regex>` = OS_Regex (classes, groups, `+`/`*`). `<match>` = OS_Match: literal substrings + only `^ $ | !`. `<match>` has NO char classes, quantifiers, or groups — prefer it (faster) when a literal test suffices.

Grounded in the official Wazuh documentation (ruleset-xml-syntax/regex.html). Validate every decoder with /var/ossec/bin/wazuh-logtest before deploying — decoder order and prematch specificity are site-specific.