I haven't tried it but here is how you could rewrite it:

```elixir
destructure [_, mahor, minor, patch, build] = 
  Regex.run %r/^(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:[\-+]([^\s]+))?$/, string

major = binary_to_integer(major)
minor = binary_to_integer(minor || "0")
patch = binary_to_integer(patch || "0")
build = case build && Regex.run(%r/^(.*?)(\d+)?$/, build) do
  [_, build] ->
    { build, 0 }
  [_, build, number] ->
    { build, binary_to_integer(number) }
  nil ->
    nil
end

{ major, minor, patch, build }
```

If you move the building parsing elsewhere, it could even be:

```elixir
destructure [_, mahor, minor, patch, build] = 
  Regex.run %r/^(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:[\-+]([^\s]+))?$/, string

{ binary_to_integer(major),
  binary_to_integer(minor || "0"),
  binary_to_integer(patch || "0"),
  build && parse_build(build) }
```