7

Is there a way to test if a given string is a versioning number or not? I have some user input and I need to verify that the string being given to me can be used as a versioning number. I've seen that PHP has a version_compare() function but that looks like compareing two versions to one another.

I am assuming the given string should be a "PHP-Standardized" version.

2
  • 2
    Use a regexp like /^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/? Commented Mar 6, 2015 at 16:33
  • The regex above isn't 100% accurate. It will get you pretty close though. Mostly because there are only certain strings that are valid at the end of a version: dev, alpha, a, beta, b, RC, rc, pl, p. All other words and characters show up as invalid. Commented Nov 25, 2016 at 13:16

3 Answers 3

11

I'm not sure if this is the best way but using the version_compare() I just ensured that it was at least 0.0.1 by filtering out 'non-version' strings:

version_compare( $given_version, '0.0.1', '>=' )

For example:

if( version_compare( $_POST['_plugin_vers'], '0.0.1', '>=' ) >= 0 ) {
    echo 'Valid Version';
} else {
    echo 'Invalid Version';
}
Sign up to request clarification or add additional context in comments.

3 Comments

Will this work with alpha and beta words in the string, too?
@OlleHärstedt, yep. From php.net: The function first replaces _, - and + with a dot . in the version strings and also inserts dots . before and after any non number so that for example '4.3.2RC1' becomes '4.3.2.RC.1'. Then it compares the parts starting from left to right. If a part contains special version strings these are handled in the following order: any string not found in this list < dev < alpha = a < beta = b < RC = rc < # < pl = p. This way not only versions with different levels like '4.1' and '4.1.2' can be compared but also any PHP specific version containing development state.
This doesn't seem to validate anything at all, all strings passes. 3v4l.org/tBAIo#v8.0.10
3
if(preg_match('/^(\d+\.)?(\d+\.)?(\*|\d+)$/', $string)){
  echo 'Valid';
} else {
  echo 'Invalid';
}

1 Comment

Just a sidenote that this works for X.X.X, but doesn't support versions with strings like 1.0.0-dev 3v4l.org/qeOlC#v8.0.10
2
$versions = [
    '1',
    '1.0',
    '1.001',
    '1.0.1',
    '1.00.1',
    '1.0.01',
    '10.0.1',
    '10.01.10',
    '1.0.0-beta',
    '1.0.0-rc1',
    '5.5.9-1ubuntu4.17',
    '\'DROP DATABASE',
    '1.2.3<script>xss</script>'
];

foreach ($versions as $version) {
    if (preg_match('#^(\d+\.)?(\d+\.)?(\d+)(-[a-z0-9]+)?$#i', $version, $matches) !== 0) {
        var_dump($matches[0]);
    } else {
        echo 'Could not find version number in string: ' . $version;
    }
    echo PHP_EOL;
}

Result:

string(1) "1"
string(3) "1.0"
string(5) "1.001"
string(5) "1.0.1"
string(6) "1.00.1"
string(6) "1.0.01"
string(6) "10.0.1"
string(8) "10.01.10"
string(10) "1.0.0-beta"
string(9) "1.0.0-rc1"
Could not find version number in string: 5.5.9-1ubuntu4.17
Could not find version number in string: 'DROP DATABASE
Could not find version number in string: 1.2.3<script>xss</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.