Needs example RegExp #32

Closed
coolaj86 opened this Issue Jun 13, 2012 · 12 comments

6 participants

@coolaj86

For convenience the regular expression that parses a valid semver should be made available on the homepage.

JavaScript:

/^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/

UPDATE: I think I've collected all of the comments and edge cases to produce a regex and test cases that are in accordance with the spec.

See test cases in JavaScript: https://github.com/coolaj86/semver-utils

@mauriciopasquier

I'm using this one for Ruby:

/\d+\.\d+\.\d+[\-[\dA-Za-z\-\.]+]?[\+[\dA-Za-z\-\.]+]?/
@JohnPeacock

Those are both wrong (in that they will "parse" illegal values). The Javascript regex will allow v2.0.0+-build.acebfde1284 and the Ruby regex would allow v2.0.0-build.acebfde1284+build.acebfde1284. In both cases, a true alternation is required to permit either a hyphen or a plus sign, but not both (and either extra bit is optional).

@mauriciopasquier

@JohnPeacock I thought that both were allowed to coexist:

"A pre-release version MAY be denoted by appending a dash (...)"
"A build version MAY be denoted by appending a plus sign (...) immediately following the patch version or pre-release version."

@coolaj86

@JohnPeacock that's exactly why there needs to some canonical regexes on the main page.

@jlfaber

The spec indicates that pre-release and build version may coexist. The following excerpt from paragraph 12

1.0.0-rc.1 < 1.0.0-rc.1+build.1

indicates that the a version with just a pre-release is lower in precedence than the same string with a build appended.

I don't disagree that a canonical regexp would be helpful, however.

@ghost

Here's my attempt at this:

/^([0-9]+\.{0,1}){1,3}(\-([a-z0-9]+\.{0,1})+){0,1}(\+(build\.{0,1}){0,1}([a-z0-9]+\.{0,1}){0,}){0,1}$/

It validates all of the examples listed on the website at this time.

EDIT: I agree with @jlfaber, so I removed the option to support the optional "v" prefix.

Original:

/^v{0,1}([0-9]+\.{0,1}){1,3}(\-([a-z0-9]+\.{0,1})+){0,1}(\+(build\.{0,1}){0,1}([a-z0-9]+\.{0,1}){0,}){0,1}$/
@jlfaber

Perhaps I've missed something, but I don't see anything in the spec that says a leading 'v' is permitted. Lots of folks prefix their versions with a v, of course, but if we're trying to document the spec itself, I don't think that should be there.

Here's what I've been using. Note that I've included "capture" parens to return the base, pre-release, and build components.

/^(\d+\.\d+\.\d+)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$/
@Omnikron13

@jlfaber All of your parens are capturing groups though so you end up capturing all sorts of things that I assume you don't wish to... You should use non-capturing groups for those you don't wish to be captured:

^(\d+\.\d+\.\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$

Given '2.0.0-rc.1+build.123' that will only capture '2.0.0', 'rc.1' & 'build.123'.
using non-capturing groups will probably also speed up the regex engine.

@ghost

@Omnikron13 Nice, it also accounts for trailing decimal points. I'll be borrowing this!

@jlfaber

@Omnikron13 Good catch on the non-capturing groups. Thanks!

@coolaj86

In order for sorting to work predictably we have to allow

1.0.0-rc.1+build.1

but disallow

1.0.0+build.1-rc.1

UPDATE: Nevermind, I see that 1.0.0+build.1-rc.1 would only have a build, as - is an allowable identifier and that the following would still be unambiguous

1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay
@Haacked
Collaborator

Hi @coolaj86 great idea! This is the repository for the spec. Would you mind submitting this as a pull request over at the website repository? https://github.com/mojombo/semver.org/

We need to consider a nice way to present this information. Should it go in the FAQ or perhaps add a "more info" link to the top header to a page that has this and other information such as links to translations.

Thanks!

@Haacked Haacked closed this Mar 13, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment