The product title.
The concentration string, or undefined when the title states none.
parseConcentration('Isopropyl Alcohol 70% (v/v) Aqueous Solution'); // "70% (v/v)"
parseConcentration('Nitric Acid 6.0 Normal Aqueous Solution'); // "6.0 Normal"
parseConcentration('Bromide Standard (w/w) 800 PPM as Br'); // "800 ppm (w/w)"
parseConcentration('Sodium Chloride, ACS Grade'); // undefined
export function parseConcentration(title: string): string | undefined {
if (typeof title !== 'string' || title.length === 0) {
return undefined;
}
const text = title.replace(/>/gi, '>').replace(/</gi, '<').replace(/≥/gi, '≥');
const method = normalizeMethod(text.match(CONCENTRATION_METHOD)?.[0]);
const withMethod = (core: string) => (method ? `${core} ${method}` : core);
// Molarity / normality outrank a percentage (a co-occurring percent is the
// solvent). Between the two, the earliest-stated wins.
const molar = text.match(/(\d+(?:\.\d+)?)\s*Molar\b/i);
const normal = text.match(/(\d+(?:\.\d+)?)\s*Normal\b/i);
if (molar && (!normal || (molar.index ?? 0) <= (normal.index ?? 0))) {
return `${molar[1]} Molar`;
}
if (normal) {
return `${normal[1]} Normal`;
}
const ppm = text.match(/(\d[\d,]*(?:\.\d+)?)\s*ppm\b/i);
if (ppm) {
return withMethod(`${ppm[1]} ppm`);
}
// Comparator (`>`/`≥`), number, optional range/`+`, then `%`.
const percent = text.match(/([<>≥≤]\s*)?\d+(?:\.\d+)?(?:\s*[-–]\s*\d+(?:\.\d+)?)?\s*\+?\s*%\+?/);
if (percent) {
return withMethod(percent[0].replace(/\s+/g, ''));
}
const gramsPerLiter = text.match(/(\d+(?:\.\d+)?)\s*g\/L\b/i);
if (gramsPerLiter) {
return withMethod(`${gramsPerLiter[1]} g/L`);
}
// A stabilizer marker with no numeric concentration, e.g. "(w/BHT)".
return method;
}
Extracts a solution concentration from a ScienceLab product title.
Handles the forms the catalog uses, in order of precedence: molarity (
0.7 Molar) and normality (0.100 Normal) — the earliest-stated of the two wins when both appear — then mass concentration (800 ppm), then a percentage (70% (v/v),20% w/v,90+%,>95%), theng/L, then a bare stabilizer marker ((w/BHT)). Molarity/normality/ppm deliberately outrank a percentage, because a percentage stated alongside them describes the solvent or matrix (1000 ppm … in 3% HNO₃,0.1 Normal in 90% Isopropanol), not the product. A v/v, w/v, or w/w method marker is appended to a percentage or ppm value.