The candidate SMILES string
True if the string is plausibly a SMILES, false otherwise
isProbablyValidSmiles("CC(=O)O") // true
isProbablyValidSmiles("[Na+]") // true (bracketed single atom)
isProbablyValidSmiles("P") // false (single character — not assumed to be phosphorus)
isProbablyValidSmiles("CC(=O") // false (unbalanced parenthesis)
isProbablyValidSmiles("hello!") // false (illegal character)
export function isProbablyValidSmiles(smiles: string): boolean {
const value = smiles.trim();
// Reject empty, single-character (a bare `P` is not assumed to be phosphorus), and oversize input.
if (value.length < 2 || value.length > MAX_SMILES_LENGTH) return false;
if (!SMILES_VALIDATE.test(value)) return false;
// The grammar does not enforce delimiter balance — verify parens/brackets close cleanly.
let parens = 0;
let brackets = 0;
for (const char of value) {
if (char === '(') parens++;
else if (char === ')') parens--;
else if (char === '[') brackets++;
else if (char === ']') brackets--;
if (parens < 0 || brackets < 0) return false;
}
return parens === 0 && brackets === 0;
}
Lightweight validity check for a SMILES string — verifies the characters are legal and that parentheses/brackets are balanced. This is a cheap guard before a network call, not a real SMILES parser; chemically-invalid but syntactically-plausible strings still pass.