[a-zA-Z]+)? # optional prefix: eg : "v" in "v1.2.3" (?P[0-9]+) # major version \.(?P[0-9]+) # minor version \.(?P[0-9]+) # patch version (?: (?P[+\-]) (?P [a-zA-Z0-9]+ # should start with a number or a letter (?: [a-zA-Z0-9.+\-]* # allow any number of letters, numbers, dots, plus and minus [a-zA-Z0-9] # should end with a number or a letter )? ) # release version )? $'; /** * The version string * * @var string */ public readonly string $version; /** * Is the version string valid * * @var bool */ public readonly bool $valid; /** * The major version * * @var int|null */ public readonly ?int $major; /** * The minor version * * @var int|null */ public readonly ?int $minor; /** * The patch version * * @var int|null */ public readonly ?int $patch; /** * The release separator * * @var string|null */ public readonly ?string $releaseSeparator; /** * The release version * * @var string|null */ public readonly ?string $release; /** * SemanticVersion constructor. * * @param string $version */ public function __construct(string $version) { $this->version = trim($version); preg_match('/' . self::SEMANTIC_VERSION_REGEX . '/', $this->version, $matches); $this->valid = !empty($matches); $this->major = is_array($matches) && isset($matches['major']) ? (int) $matches['major'] : null; $this->minor = is_array($matches) && isset($matches['minor']) ? (int) $matches['minor'] : null; $this->patch = is_array($matches) && isset($matches['patch']) ? (int) $matches['patch'] : null; $this->releaseSeparator = is_array($matches) && isset($matches['release_separator']) ? $matches['release_separator'] : null; $this->release = is_array($matches) && isset($matches['release']) ? $matches['release'] : null; } public function __toString(): string { return $this->version; } /** * @return array{ * version: string, * valid: bool, * major: int|null, * minor: int|null, * patch: int|null, * release_separator: string|null, * release: string|null * } */ public function toArray(): array { return [ 'version' => $this->version, 'valid' => $this->valid, 'major' => $this->major, 'minor' => $this->minor, 'patch' => $this->patch, 'release_separator' => $this->releaseSeparator, 'release' => $this->release, ]; } /** * @return array{ * version: string, * valid: bool, * major: int|null, * minor: int|null, * patch: int|null, * release_separator: string|null, * release: string|null * } */ public function jsonSerialize(): array { return $this->toArray(); } }