string substr (size_t pos = 0, size_t len = npos) const;
The second parameter holds for the length of the substring, not for the index of the end of the capture.
std::string::substr[
^]
So, yes, the function is working properly; you just misused its parameters :)