This would still match for a string like "foo: " which I think it shouldn't. I would propose:

    if (sub_index != std::string::npos && // needle is found
        sub_index > 0 && // does not start with needle
        space_index > sub_index && // no spaces before needle
        text.length() > space_index + 1) // remaining text is not empty