The string to extract a purity/grade from (e.g. a product name)
The percentage token (e.g. "≥99.8%"), a grade label (e.g. "ACS Grade"), or nothing
findPurity("Sodium Metal ≥99.8%") // "≥99.8%"
findPurity("Acetonitrile HPLC - 1 L") // "HPLC Grade" (no percentage, grade fallback)
findPurity("Sodium, Reagent (ACS) - 500 G") // "ACS Grade"
findPurity("Ships in 4-6 business days") // "Ungraded"
findPurity("") // undefined
export const findPurity = (value: string): string | undefined => {
if (!value || typeof value !== 'string') return;
// Strip HTML first so inline CSS (e.g. style="width: 100%") isn't read as a purity.
const clean = value.replace(/<[^>]+>/g, ' ');
// A percentage (with optional comparator) is the most specific signal, so it wins over a grade.
// Same shapes parsePurity tolerates — comparator, European comma decimal, "or better" plus —
// since both read the same supplier copy; only the return type differs.
const token = clean.replace(/\s+/g, '').match(/[<>≤≥≈]?\d{1,3}(?:[.,]\d+)?\+?%/)?.[0];
const numeric = Number(token?.match(/\d+(?:[.,]\d+)?/)?.[0].replace(',', '.'));
if (token && !Number.isNaN(numeric) && numeric > 0 && numeric <= 100) {
return token;
}
return parseGrade(clean);
};
Extracts a purity/grade descriptor from a string, as a string. Unlike parsePurity (which returns only a numeric percentage), this keeps the qualifier — so a comparator percentage like
"≥99.8%"or">99%"is preserved verbatim — and, when no valid percentage is present, falls back to a recognized chemical grade ("ACS Grade","HPLC Grade", …) via parseGrade, which means an unrecognized string comes back as"Ungraded"rather than nothing. Only an empty or non-string input returns nothing. Built forProductBuilder.setPurity, whose Purity column shows either kind.