JavaScript · Case Folding and Normalization

Case Folding and Normalization

import * as stringzilla from 'stringzilla';import { Utf8UncasedNeedle } from 'stringzilla';import { Utf8UncasedNeedleConstructor } from 'stringzilla'; 6.0.0-rc.1 · 91a27bdd

These functions operate on UTF-8 encoded buffers and apply full Unicode case folding. Each accepts an optional trailing validate boolean; when true, the input is checked for valid UTF-8 and an error is thrown otherwise.

utf8UncasedFold returns a new Buffer with the input case-folded. The result may be longer than the input because some code points expand when folded.

assert.strictEqual(sz.utf8UncasedFold(Buffer.from("Straße")).toString(), "strasse");

utf8UncasedFind performs a case-insensitive substring search. It returns an object { index, length }, both BigInt, where index is the matched byte offset, or -1n if not found, and length is the matched byte length, which can differ from the needle’s length under folding.

const { index, length } = sz.utf8UncasedFind(Buffer.from("Hello WÖRLD"), Buffer.from("wörld"));

The Utf8UncasedNeedle class prepares a needle once for repeated searches, amortizing the folding setup. It keeps its own copy of the needle bytes, so later writes to the source buffer do not affect it. An empty needle matches at index 0n with length 0n, in both forms. Construct it with the needle buffer and an optional validate flag, then call findIn(haystack, validate?), which returns the same { index, length } object.

const needle = new sz.Utf8UncasedNeedle(Buffer.from("wörld"));
needle.findIn(Buffer.from("Hello WÖRLD")); // => { index, length }

§ Unicode Normalization

utf8Norm converts a UTF-8 buffer into one of the four Unicode normal forms, passed as a Utf8NormalForm constant: NFD, NFC, NFKD, or NFKC. It returns a new Buffer and accepts the same optional trailing validate boolean as the case-folding functions.

const decomposed = Buffer.from("café"); // "e" followed by a combining acute
assert.strictEqual(sz.utf8Norm(decomposed, sz.Utf8NormalForm.NFC).toString(), "café");

utf8FindDenormalized checks a buffer against a normal form without rewriting it. It returns the byte offset of the first violation as a BigInt, or -1n when the input is already normalized.

assert.strictEqual(sz.utf8FindDenormalized(Buffer.from("café"), sz.Utf8NormalForm.NFC), -1n);
assert.strictEqual(sz.utf8FindDenormalized(decomposed, sz.Utf8NormalForm.NFC), 3n);

API

Types

Utf8NormalFormValueOne of the Utf8NormalForm constants: NFD, NFC, NFKD or NFKC.
stringzilla.d.ts:43 ↗
type Utf8NormalFormValue = 0 | 1 | 2 | 3
InterfaceUtf8UncasedNeedleUncased UTF-8 needle prepared once, over its own copy of the bytes, for repeated searches.1
stringzilla.d.ts:101 ↗
interface Utf8UncasedNeedle
findInFinds the first occurrence of the needle in haystack under full Unicode case folding.
stringzilla.d.ts:109 ↗
findIn(haystack: Buffer, validate?: boolean): FindResult

Parameters

haystackBufferUTF-8 encoded haystack
validatebooleanIf true, validates UTF-8 and throws on invalid input

Returns

The byte index and matched byte length; index is -1n if not found
InterfaceUtf8UncasedNeedleConstructorConstructs a Utf8UncasedNeedle.1
stringzilla.d.ts:113 ↗
interface Utf8UncasedNeedleConstructor
Utf8UncasedNeedleConstructor
stringzilla.d.ts:118 ↗
new Utf8UncasedNeedleConstructor(
    needle: Buffer,
    validate?: boolean,
): Utf8UncasedNeedle

Parameters

needleBufferUTF-8 encoded needle
validatebooleanIf true, validates UTF-8 and throws on invalid input