def parse(cls, version_string):
        """Parses a ``version_string`` and returns a :py:class:`~Version`
        object.
        """
        match = RE.match(version_string)
        if match:
            major_str, minor_str, patch_str, postrelease_alpha, \
                postrelease_digit, prerelease_str, build_metadata = \
                match.groups()

            if postrelease_digit:
                postrelease = int(postrelease_digit)
            else:
                postrelease = postrelease_alpha

            # A well-defined version cannot both have a pre- and a
            # post-release identifier.
            if postrelease and prerelease_str:
                raise InvalidVersionExpression(version_string)

            major = int(major_str)

            if minor_str:
                minor = int(minor_str)
            else:
                minor = 0

            if patch_str:
                patch = int(patch_str)
            else:
                patch = 0

            if prerelease_str:
                try:
                    prerelease = int(prerelease_str)
                except ValueError:
                    prerelease = prerelease_str
            else:
                prerelease = None

            return cls(major, minor, patch,
                       postrelease, prerelease, build_metadata)

        else:
            raise InvalidVersionExpression(version_string)