The HTML string to search for a formula
The formula with proper sub/superscript formatting, or undefined if none is found
findFormulaInHtml('foobar K<sub>2</sub>Cr<sub>2</sub>O<sub>7</sub> baz') // "K₂Cr₂O₇"
findFormulaInHtml('C<sub>18</sub>H<sub>14</sub>N<sub>2</sub>O') // "C₁₈H₁₄N₂O"
findFormulaInHtml('C<sub>20</sub>H<sub>20</sub>O<sub>5</sub>·K') // "C₂₀H₂₀O₅·K"
findFormulaInHtml('Just some text') // undefined
https://regex101.com/r/H6DXwK/6 - Regex pattern explanation
export const findFormulaInHtml = (html: string): string | undefined => {
// Collect every candidate and keep the most likely one (see findFormulaInText). The subscript
// token here is the HTML-only `<sub>`/`<sup>` tag; the rest of the grammar is shared.
const taggedSub = '<su[bp]>[1-9][0-9]*</su[bp]>';
const best = pickBestFormula([...html.matchAll(buildFormulaPattern(taggedSub))].map((m) => m[0]));
if (best === undefined) {
return;
}
return best
.replace(/<sub>(\d+)<\/sub>/g, (_match, p1) => subscript(p1 || ''))
.replace(/<sup>(\d+)<\/sup>/g, (_match, p1) => superscript(p1 || ''));
};
Match for a chemical formula (with or without subscript tags) in a string of html, converting
<sub>/<sup>tags to unicode sub/superscripts. Numbers that aren't tagged (e.g. a salt/hydrate coefficient denoting how many of the whole molecule) are matched but left as regular digits.Handles:
C<sub>18</sub>…);KN(C(O)CH<sub>2</sub>)<sub>2</sub>);·/•/*separator, with an optional leading coefficient that may be a number, a<sub>-tagged number, or a variablex/n(…O·xH<sub>2</sub>O,… • <sub>4</sub>K,…O<sub>5</sub>·K).Element symbols gate the match — at least two element/bracket "units" are required — so ordinary prose isn't mistaken for a formula. A clean, subscript-free formula like
KBris a single unit and is intentionally NOT matched here (callers store those verbatim viaisMoleForm).