After gh-152033, \d outside a set compiles to a bare CATEGORY opcode with a fast REPEAT_ONE / count path. But a character set containing exactly one category — [\d], [\w], [^\s], … — is still wrapped in an IN block, even though [\d] = \d and [^\d] = \D.
Such sets can compile to the same bare CATEGORY opcode (the negated form via the complementary category, CH_NEGATE), reusing gh-152033's fast path. @serhiy-storchaka
Smaller byte code
The IN wrapper is removed, so each single-category set shrinks:
pattern
before
after
saved
[\d]+, [\w]+, [\s]+
16
13
−3 words
[^\d]+, [^\w]+, [^\s]+
17
13
−4 words
Benchmark
Benchmark
base
after
[^\s]+
1.58 us
559 ns
2.82x
[^\d]+
1.65 us
911 ns
1.81x
[^\w]+
2.65 us
1.72 us
1.55x
[\s]+
974 ns
634 ns
1.54x
[\d]+
1.06 us
740 ns
1.43x
findall [^\s]+
91.5 us
69.0 us
1.33x
[\w]+
1.49 us
1.15 us
1.30x
findall [\w]+
116 us
90.5 us
1.29x
Real-world usage
Single-category sets — especially the negated [^\s] / [^\d] / [^\w], which
people write instead of \S / \D / \W are used, a few examples:
Activity
gh-152056: Compile single-category character sets to a bare CATEGORY …
StanFromIreland commented on Aug 10, 2026
Triage: Can this be closed as completed?