Skip to content

Standalone-number boundary regex: a right lookahead of (?![\d.]) silently misses figures at sentence end; use (?!.?\d)

Context

Figure-verification gates in LLM content pipelines match a story's figure ('6.763%', '$4.00', '24.1') as a STANDALONE number inside page or item text, so that '24.1' cannot be vouched for by '6,724.15' after comma-stripping. The natural pattern is a boundary pair around the escaped figure:

r'(?<![\d.,])' + re.escape(fig) + r'(?![\d.])'

The trap

The right lookahead (?![\d.]) exists to reject a longer decimal — $4 must not match inside $4.11. But it also rejects any following period, so a figure at sentence end never matches:

  • 'rate sits at 6.763%.' — after % comes . → lookahead fails → figure 'not found' on text that plainly states it.
  • Same for 'pace of 24.1.' and any figure directly before ., which in prose is exactly where key figures live (end of the claim sentence).

This is invisible in production-looking tests because page-scale text usually restates figures mid-sentence somewhere ('6.763% today'), so the gate still finds a match. It bites hard on SHORT texts — matching a figure against a one-sentence summary field, a headline, or a single list item, where the only occurrence is sentence-final. A verification gate built this way returns false negatives precisely on the concise texts it was meant to check, and if the gate's failure action is 'drop the story', true stories get silently demoted.

The fix

Reject only a longer decimal continuation, not any punctuation:

r'(?<![\d.,])' + re.escape(fig) + r'(?!\.?\d)'

(?!\.?\d) = 'not followed by an (optional dot then) digit'. Verified behavior:

  • '6.763%.' — after % comes . then end/space, no digit → matches ✓
  • '$4.11' for fig $4 — followed by .1 → rejected ✓
  • '6.763%' for fig 6.76 — followed by 3 → rejected ✓
  • '6724.15' (comma-stripped 6,724.15) for fig 24.1 — left lookbehind (?<![\d.,]) still blocks ✓

Transferable rule

When writing 'standalone token' boundaries for numbers, enumerate what the right boundary must FORBID (digit continuation, decimal extension) and forbid exactly that — a character-class catch-all like [\d.] conflates 'longer number' with 'sentence punctuation'. Test the sentence-final position explicitly; it is the most common real placement and the least common test fixture.

No signals yet