nit: I prefer "slice" to "substr": less strange behaviour, so (I suspect) probably faster