2

I'm trying to make a regex that matches a semantic version (SemVer) 2.0.0. This is my first try:

^(?'major'\d+)\.(?'minor'\d+)(?:\.(?'patch'\d+))?(?:-(?'preRelease'(?:(?'preReleaseId'[0-9A-Za-z-]+)\.?)+))?(?:\+(?'build'(?:(?'buildId'[0-9A-Za-z-]+)\.?)+))?$

RegEx101

This passes my smoke tests, but when I try to actually make it a NSRegularExpression, I get this:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=2048 "The value “^(?'major'\d+)\.(?'minor'\d+)(?:\.(?'patch'\d+))?(?:-(?'preRelease'(?:(?'preReleaseId'[0-9A-Za-z-]+)\.?)+))?(?:\+(?'build'(?:(?'buildId'[0-9A-Za-z-]+)\.?)+))?$” is invalid." UserInfo={NSInvalidValue=^(?'major'\d+)\.(?'minor'\d+)(?:\.(?'patch'\d+))?(?:-(?'preRelease'(?:(?'preReleaseId'[0-9A-Za-z-]+)\.?)+))?(?:\+(?'build'(?:(?'buildId'[0-9A-Za-z-]+)\.?)+))?$}: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift, line 181

Why? I can't find anything online about what NSRegularExpression expects/accepts, so I don't know what I did wrong here.


Swift code:

public static let regex = try! NSRegularExpression(pattern:
    "^(?'major'\\d+)\\." +
    "(?'minor'\\d+)" +
    "(?:\\.(?'patch'\\d+))?" +
    "(?:-(?'preRelease'(?:(?'preReleaseId'[0-9A-Za-z-]+)\\.?)+))?" +
    "(?:\\+(?'build'(?:(?'buildId'[0-9A-Za-z-]+)\\.?)+))?$",
                                                   options: .caseInsensitive)
Ky -
  • 30,724
  • 51
  • 192
  • 308

2 Answers2

1

It appears you are trying to use named groups in your regex. NSRegularExpression named groups use angle brackets rather than single quotes which you have in your regex. Try using the syntax

`(?<groupName>...)`

for your named capture groups.

Josh Withee
  • 9,922
  • 3
  • 44
  • 62
0

Here a regex that meets that spec. I used PCRE style for illustration purposes: named groups. You may need to remove the <groupnames> and make normal groups out of them. You may want to add ^ and $ to match start and end of sting:

(?<version_core>(?<major>(?:[0-9]|[1-9][0-9]+))\.(?<minor>(?:[0-9]|[1-9][0-9]+))\.(?<patch>(?:[0-9]|[1-9][0-9]+)))(?:-(?<pre_release>(?:0|[1-9A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9A-Za-z-][0-9A-Za-z-]*))*))?(?:\+(?<build>[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?

Regular expression visualization

Debuggex Demo

inetphantom
  • 2,498
  • 4
  • 38
  • 61
  • Might wanna upload that image directly to SO :) – Ky - Dec 07 '18 at 16:32
  • Also, your regex doesn't match `1.0`, which is a valid SemVer since the PATCH is not required. Here: https://www.debuggex.com/r/bINTxOgO8E88Z5n_ – Ky - Dec 07 '18 at 16:35
  • 1
    @BenLeggiero `1.0` is not valid - patch version is needed - https://github.com/semver/semver/blob/master/semver.md#backusnaur-form-grammar-for-valid-semver-versions – inetphantom Dec 07 '18 at 21:14