$re = '#^(?P<major>\d+)(?:\.(?P<minor>\d+)(?:\.(?P<build>\d+)(?:\.(?P<revision>\d+))?)?)?(?:-(?P<prerelease>\w+)(?:[-\.](?P<version>\d+))?)?$#m';
$str = '1.0.10123.0
1.0.10123.0-preview
1.0.10123.0-beta-1
1.0.10123.0-beta.2
0.9-beta-2
2.1.0
2.1.1
2.1.1-preview
2.1.1-beta.1
2.1.1-rc-4
1.8.9
2.5.1
5.2.1
6.5
11.5
1.16
5.4.1.1
5.4.1.1
5.4.1.1
1.4
1.4.2
1.9.1.8
1.6.37
3.1
15
2
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15.112.1
15
15.112.1
15.112.1
15.112.1
17.14.15
17.14.15
17.8.8
1.1.2
1.1.2
1.1.1
15
13.0.3
5.4
15.0.2
15.0.2
15.0.2
15
1.3.6
1.1.1
8.5.2
3.0.0
9.0.107
9.0.537
9.0.537
9.0.537
4.2.0
9.0.0
9.0.1
9.0.0
6.0.0
3.0.0
7.0.0
3.0.0
1.8.11
1.0.119
5.2.3
6.1
6.1
22
1
1.0.3240.44
3.5.5
3.5.5-preview
3.5.5-preview.1
3.5.5-preview-2
3.2
3.2-beta';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php