Code readingHow-to

Barcode scanner regex parsing: prefix, suffix and capture groups

Set up barcode scanner regex parsing the right way: prefix and suffix disable the regex, the expression needs capture group 1, and the scan array needs a cap.

LumaSpec Vision11 min read Share on LinkedIn

On this page 10 sections
  1. 01Prefix and suffix, or regex: pick exactly one
  2. 02Why a valid regex logs nothing: capture group 1
  3. 03Worked example: parsing 412-TRACER order codes
  4. 04The scan array has no maximum size
  5. 05Configure the component in eight steps
  6. 06Checks before you call it done
  7. 07When a silent parser is not a regex problem
  8. 08Readers that feed the parser
  9. 09Thirty-second checklist
  10. 10Questions

You wired the scanner in, the decoded strings arrive, and now the barcode scanner input component has to turn raw scans into clean values. Two settings decide that: the prefix and suffix pair, and the regex. They do not combine — one quietly disables the other — and the regex carries a format requirement that is easy to miss and swallows valid expressions whole. On top of that, every scan appends a new index to the scan array, and nothing caps it for you. This guide gives you the choice between framing and regex, the exact expression format the component expects, a worked match on a real order-code pattern, and the truncation your host code needs before the array outgrows the screen.

Prefix and suffix, or regex: pick exactly one

The component offers two parsing mechanisms, and they are mutually exclusive. Set a prefix and a suffix, and the regex is never evaluated: the component waits for the prefix, keeps everything up to the suffix, and hands that slice to your application. Leave both fields blank, and the regex becomes the parser. There is no third mode — a non-matching regex does not fall back to framing, and framing never loosens into a pattern match.

Choose by the shape of the codes, not by preference:

  • One exact, invariable marker pair around every scan — a fixed part-number envelope: use prefix and suffix. It cannot mis-parse, and it switches the regex off, so leave that field empty.
  • A pattern family with variable content — three digits, a hyphen, five to eight letters: use the regex, with both framing fields blank.
  • No way to add framing characters on the device side, because the customer's scanners are locked: the regex is the only path, not the fallback. Fold any fixed preamble into the expression itself.

If you control the scanner configuration, framing can also move down to the device — many readers append their own terminating character, the way scanner suffix setup for HMI text entry shows. For framing at the component itself, the field-by-field walk-through is prefix and suffix framing for barcode scanner input; for streams that arrive with no preamble at all, start from barcode scanner capture without a prefix.

Why a valid regex logs nothing: capture group 1

The format requirement is the one that costs an afternoon. The component does not run your expression as written: it applies it as a single capture group and returns group number 1, internally in the form (pattern){1}, and that format does not appear in the component's help text. An expression that matches the string but defines no capturing group returns nothing — the component has a match and no group 1 to log, so the read history stays empty while the same expression tests green in any online builder.

The fix is one pair of parentheses around the whole pattern:

^\d{3}-[a-zA-Z]{5,8}$ becomes ( ^\d{3}-[a-zA-Z]{5,8}$ ){1} written without spaces as (\^\d{3}-[a-zA-Z]{5,8}\$){1}

Worked example: parsing 412-TRACER order codes

The production line in question prints product codes as three digits, a hyphen, then five to eight letters; 412-TRACER is a real shape. The scan stream also carries noise — operator badges, double reads, and partial codes off a torn label.

Inputs, with where each comes from:

  • Code shape: 3 digits + 1 hyphen + 5 to 8 letters, from the label specification.
  • Shortest valid code: 3 + 1 + 5 = 9 characters. Longest: 3 + 1 + 8 = 12 characters.
  • Known-good string: 412-TRACER, which is 3 + 1 + 6 = 10 characters.
  • Known-bad strings: 412-TR (2 letters), 412-TRACERSAND (9 letters), 41A-TRACER (letter in a digit position).

The rule in words: match the whole string from the first character to the last, and return the entire match as group 1. The expression for the component, anchored and wrapped:

(^^\d{3}-[a-zA-Z]{5,8}$){1}

The match on 412-TRACER, step by step:

  1. ^ pins the match to the first character.
  2. \d{3} consumes 4, 1, 2 — exactly three digits.
  3. The literal hyphen in the expression consumes the hyphen in the code.
  4. [a-zA-Z]{5,8} consumes TRACER — 6 letters, inside the 5-to-8 range.
  5. $ demands the string ends here, and it does: 3 + 1 + 6 = 10 characters consumed out of 10.
  6. Group 1 spans the whole expression, so the parsed value is 412-TRACER, and it lands as one new array index.

The rejects fail for three different reasons. 412-TR offers the letter class only 2 of its required 5 to 8 characters. 412-TRACERSAND offers 9 letters, one above the maximum of 8, and $ refuses to close the match early. 41A-TRACER fails at the third digit, because A is not in \d.

Decision: a code family of 9 to 12 characters in this shape takes exactly this wrapped expression with both framing fields blank, and every non-matching scan produces no parsed value — that is the filter working. When the family changes, only the quantifier moves: an 8-to-13-character family needs {4,9}, because 3 + 1 + 4 = 8 and 3 + 1 + 9 = 13. Nothing else in the configuration changes.

The scan array has no maximum size

The second question has a short answer: there is no explicit limit. Every scan adds one index, and the host owns truncation. Nothing wraps around and nothing raises an error — the array grows until the process runs short of memory or the table bound to it slows the screen.

Size it before dismissing it. An entry holds the decoded string, a timestamp and some metadata; take roughly 200 bytes per entry as an estimate. At one scan per second, a three-shift day is 86,400 scans:

entries per day = 1 scan/s × 86,400 s = 86,400 memory per day = 86,400 × 200 B ≈ 17 MB memory per year ≈ 6 GB

Six gigabytes held by a component nobody watches. Two lines of host code end it: on each successful read, consume the newest index and clear the array. If you need history, keep a ring of the last 100 entries — a counter running 0 to 99 across a buffered read array is a standard pattern in vision-system PLC code, and it bounds memory to 100 × 200 B = 20 KB. Draining the newest value into a controller deserves its own design work: barcode reader PLC communication: plan a reliable link. Do the truncation inside the scan event itself, or handling one scan will retrigger the handler — the exact trap unpacked in barcode scan event handling without recursive updates.

Configure the component in eight steps

  1. Export the current reader and screen configuration. One file restores a working line in minutes; the habit is laid out in vision reader configuration backup before troubleshooting.
  2. Decide who parses: one exact delimiter pair on every scan means prefix and suffix with the regex left empty; a pattern family means the regex with both framing fields blank.
  3. Check that the window length spans the longest real code — 12 characters in this example — so the expression receives whole strings.
  4. Leave prefix and suffix blank.
  5. Write the expression anchored at both ends, then wrap it: (^^\d{3}-[a-zA-Z]{5,8}$){1}.
  6. Test it in any online regex builder against ten real decoded strings — seven that must pass, three that must fail — before it goes near the line.
  7. Scan one known-good and one known-bad code: exactly one new index should appear, only for the good code.
  8. Add truncation on the scan event — consume the newest index, then clear the array or keep the last 100 entries.

Checks before you call it done

  • Break test. Temporarily break the regex by deleting its final parenthesis, then scan. If logging stops, the regex is the live parser. If scans still log, framing is active and a prefix or suffix is set somewhere.
  • Group test. Enter (.*){1}: it must log every scan verbatim. If it does and your real expression does not, the expression is wrong, not the format.
  • Reject test. Scan the three known-bad codes; none may add an index.
  • Length test. Scan the shortest and longest production codes — 9 and 12 characters here.
  • Array test. Scan five times quickly; the array must hold only what your truncation allows.
  • Confidence test. A scan that passes the pattern is only as good as the image behind it — grade it as described in barcode read confidence: how to judge whether a decode is trustworthy.
  • Display test. If the framed value arrives but loses its markers on screen, the loss is display-side — the same symptom as prefix and suffix loss on HMI displays.

When a silent parser is not a regex problem

Nothing logs, the expression is valid, and it is wrapped. Work the causes in this order:

  1. Framing is set. Any prefix or suffix value switches parsing to framing and the regex is ignored. Run the break test; if scans still log, clear both fields.
  2. No capture group. The component returns group 1, and a match without a group returns nothing. Wrap the whole expression.
  3. The expression does not fit the real codes. Anchors positioned against a preamble the device prepends, or quantifiers sized for the wrong family. Paste ten real decoded strings into a regex builder and read the failures.
  4. No scans arrive at all. A silent pipe is an interface fault, not a parsing fault — walk the power and interface checks for USB adapters before touching the expression. If the host consumes keystrokes rather than decoded strings, the regex belongs on the screen's key-event layer, as in regex on key events for scanner input.
  5. The characters are wrong, not the parsing. Glare that turns 0 into O or 8 into B defeats any expression. Fix the light first: a polarizing lens cover over the reader optics removes the specular hotspot before the decoder ever runs.
Code reader accessoriesHikrobot MV-SC3000-C-HP Smart camera square semi-polarizing lens coverMV-SC3000-C-HP$39.00View part

Light boards and protective covers for the same purpose round out the reader accessories range.

Readers that feed the parser

Parsing quality starts at the reader. At one end, the LS-CRD-0047 is a compact fixed reader with a 1.2 MP sensor, a 60-120 mm reading distance and USB 2.0 — a bench station where the host does the parsing over a short cable. At the other, the MV-ID3013PM-12M-WBN is a Fast Ethernet code reader with a 12 mm focal length, for a line position feeding the same host over the plant network. When you re-aim either one, keep any laser aiming beam below eye level and never look into the aperture.

Fixed code readersCompact fixed industrial barcode reader, 1.2 MP, USB 2.0, 60-120 mm reading distance (LS-CRD-0047)LS-CRD-0047
Resolution
Up to 3 MP
Shutter
Global
$559.00View part
Fixed code readersHikrobot MV-ID3013PM-12M-WBN 12mm focal length 1.3 MP Compact Industrial Code ReaderMV-ID3013PM-12M-WBN
Interface
Fast Ethernet
Resolution
Up to 3 MP
$1,979.00View part

Filter every fixed model in the camera and reader finder, browse the fixed code readers range, and if the inspection should run on the device itself with no host parsing at all, smart cameras put decode and checks in one housing.

Thirty-second checklist

  • Prefix and suffix blank, or the regex empty — never both set.
  • Whole expression inside one capturing group: (pattern){1}.
  • Anchored at both ends: ^ and $.
  • Quantifiers sized from the code-family arithmetic: 9 to 12 characters here.
  • Ten real strings tested, three of them rejects.
  • Break test run — the regex is the live parser.
  • Truncation in place on the scan event: clear on read, or a 100-entry ring.
  • Configuration export saved before and after the change.

If the expression is right and the reads are still weak, send ten sample label images through the contact page and we will match a reader, lens and light to them.

Questions

Do prefix and suffix need values for the regex to run?

No — the opposite. Leave both fields blank and the expression becomes the parser; fill in either field and the expression is never evaluated at all. A component that logs nothing with a valid expression usually has either a framing value still set or a pattern with no capture group; clear the fields and wrap the pattern before changing anything inside it.

Is the {1} quantifier actually required?

As a quantifier it does nothing — a group repeated once is just the group. What matters is the pair of capturing parentheses around the entire pattern, because the component returns group number 1 and a match without a group yields no value. Writing (pattern){1} satisfies both requirements at once. Keep the parentheses; the {1} is harmless, and once the group is there, leaving the quantifier off costs nothing.

What is the maximum number of scans the array can hold?

There is no built-in maximum. One new index is added on every scan, and the host must truncate the array itself: clear it after each consumed read, or keep a ring of the last 100 entries, which bounds memory to about 20 KB at roughly 200 bytes per entry. Left alone at one scan per second, the array retains on the order of 17 MB per day. The component raises no warning as it grows.

Which should you configure: regex, or prefix and suffix?

Decide by code shape. One exact, invariable marker pair around every scan: prefix and suffix — it cannot mis-parse, and it switches the regex off. Any family with variable content — digit counts, letter ranges, lengths between 9 and 12 characters — takes the regex with both framing fields blank. When you cannot add framing characters on the customer's scanners, the regex is the only path, not the fallback option.

Where should the array truncation live?

In your host code, on the scan event itself — not on a timer and not in the display layer. Consume the newest index first, then clear the array or drop everything beyond the last 100 entries. Running it on the event guarantees the array never outlives a single scan between cleanups, and it avoids the recursive-update trap, where handling one scan triggers the handler again. Bind the display to the newest index only.

Can a regex catch a misread such as one letter swapped for another?

No. A regex checks shape, not truth: 412-TRACEN fits ^\d{3}-[a-zA-Z]{5,8}$ exactly and is still the wrong part. Substitutions that stay inside the character classes pass every pattern check. Catch them upstream — fix glare with light placement or a polarizing cover on the reader, and grade each decode with a read-confidence check so suspect scans are flagged rather than trusted because they matched the pattern.