Skip to content

fix(match): include last word in capture groups spanning wildcards - #1213

Merged
spencermountain merged 1 commit into
spencermountain:masterfrom
xianjianlf2:fix/capture-group-greedy-1139
Jul 18, 2026
Merged

fix(match): include last word in capture groups spanning wildcards#1213
spencermountain merged 1 commit into
spencermountain:masterfrom
xianjianlf2:fix/capture-group-greedy-1139

Conversation

@xianjianlf2

Copy link
Copy Markdown
Contributor

Fixes #1139

Symptom

A named capture group that wraps a greedy ./.* wildcard together with surrounding tokens drops the tokens after (and mis-sizes the span around) the wildcard:

nlp('one two three after').match('[<all>one . after]').group('all').text()
// actual:   'one two three'
// expected: 'one two three after'

Reproduced by @spencermountain in the issue thread.

Root cause

In src/1-one/match/methods/match/steps/astrix.js, doAstrix sets the group result with:

g.length = skipto - state.t

The assignment overwrites whatever length earlier regs in the same group had already contributed, so the group is re-anchored to just the wildcard span. The tokens captured before the wildcard are dropped from the group, and the trailing literal ends up outside the reported range.

Fix

Accumulate instead of overwrite:

g.length += skipto - state.t

Leading tokens stay in the group, and the trailing literal is appended by the normal match loop as before.

Tests

Added tests/two/match/greedy-capture.test.js covering the issue's repro plus variants (leading literal + wildcard, wildcard + trailing literal, group starting at the wildcard, and greedy min/max behavior). Full suite passes: 13,419 assertions, 0 failures (npm test).

A capture group that wrapped a greedy wildcard together with tokens
before it, e.g. `[one .* after]`, dropped the tokens captured before
the wildcard (and any trailing literal), returning "one two three"
instead of "one two three after".

`doAstrix` overwrote the group's length with the wildcard span
(`g.length = skipto - state.t`) instead of accumulating onto the
length already contributed by earlier regs in the same group. Switch
to `g.length += skipto - state.t` so leading tokens are preserved;
the trailing literal is then appended by the normal match loop.

Closes spencermountain#1139
@spencermountain

Copy link
Copy Markdown
Owner

wow, thank you!
this is very helpful!!

@spencermountain
spencermountain merged commit 23f0dd8 into spencermountain:master Jul 18, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Last word missing from capture groups when . syntax used

2 participants