2

I have a PHP app that get's a play store app data and I want to check if the data I am getting is the version number.

A version number can be 0.0.1 to 99.99.99 or I may be wrong with the version number limitations.

How can I properly use regular expressions to handle this job?

This is how I currently do it:

$list = ["hello", "0.23.2", "world"];

foreach($list as $l) {
    if (checkIfValidVersion($l)) {
       echo "valid version!";
    }
}

function checkIfValidVersion ($someString) {
    $split = explode(".", $someString);
    $isValid = false;

    foreach($split as $s) {
        $isValid = is_numeric($s) ? true : false;
    }

    return $isValid;
}
6
  • 1
    Explode by . and compare every item. Commented Mar 11, 2019 at 13:12
  • Are you sure that 99.99.99 is the highest version number? That seems a little short-sighted considering that Chrome is up to 72.x.x publically and 75.x in Canary Commented Mar 11, 2019 at 13:15
  • @MonkeyZeus I think I need to have more research regarding on that. Thanks! Commented Mar 11, 2019 at 13:18
  • Definitely do more research because it looks like 1.1-demo could be valid. developer.android.com/studio/publish/versioning Commented Mar 11, 2019 at 13:55
  • Is there a reason for not knowing if you are dealing with a version number? If Google Play has an available API then I would imagine that the version is properly labeled within a JSON response. Commented Mar 11, 2019 at 13:58

6 Answers 6

4

Simple regex would be \d+\.\d+\.\d+.

For php you can use preg_match. Check example on this link.

p.s. this is not strict check like version should be atleast 0.0.1 or max should be 99.99.99. It just checks for a pattern like below.

<number><dot><number><dot><number><dot>
Sign up to request clarification or add additional context in comments.

5 Comments

It is worth mentioning, if OP really did want to prevent numbers over 99 like their question implies, this will not restrict that.
I think you are missing a period. \d+\.\d+\.\d+
@MonkeyZeus Thanks, I just noticed now. (Updated answer).
This is awesome. Will try this with my current implementation.
@wobsoriano if my answer worked, kindly care to mark it as solved.
4

Use:

^(\d?\d)\.(\d?\d)\.(\d?\d)$

That regex will match three groups of 1 or 2 digit numbers separated by dots. It is good to use ^ and $ with preg_match to make sure it will match the whole string and not a string containing the version part, e.g. something1.0.0something.

Examples:

$pattern = "/^(\d?\d)\.(\d?\d)\.(\d?\d)$/";
preg_match($pattern, "1.0.0"); // Match
preg_match($pattern, "99.99.99"); // Match
preg_match($pattern, "99.699.99"); // Not match

1 Comment

plus 1 for ^ and $. I forgot to include in my answer.
3

Assuming, as your examples in your question, you just want to match exactly 3 sets of numbers (assuming they can only be 2 digits containing only 0-9) check my solution here

[0-9]{1,2}\.[0-9]{1,2}\.?[0-9]{1,2}

This however has a few issues, as it won't work on less than 3 sets of digits, now if the play store doesn't allow that, great, but be aware that with the above regex version numbers like 1.0 and 1.1 will not match

3 Comments

this regex will work even if there's no . e.g. 666666
You may also want to check out this pretty thourougly-vetted answer stackoverflow.com/questions/82064/…
Thank you for this @zack6849! Will try it out.
2

If you want to enforce the lower limit of 0.0.1 then this will work:

<?php
function is_valid_version( $version )
{
    // Assume the input is invalid
    $return = false;

    // Make sure we can explode() the input
    if( is_scalar( $version ) )
    {
        // Explode on periods
        $version = explode( '.', (string)$version );

        // We should have exactly items
        if( count( $version ) === 3 )
        {
            // All three items should be digits
            if(
                ctype_digit( $version[ 0 ] ) &&
                ctype_digit( $version[ 1 ] ) &&
                ctype_digit( $version[ 2 ] )
            )
            {
                // At least one digit needs to not be zero
                // 0.0.0 should be invalid
                // If you want the upper limit to be 99.99.99 then this is where you should do it
                if(
                    (int)$version[ 0 ] !== 0 ||
                    (int)$version[ 1 ] !== 0 ||
                    (int)$version[ 2 ] !== 0
                )
                {
                    $return = true;
                }
            }
        }
    }

    return $return;
}

var_dump( is_valid_version( '1.2.3' ) ); // true
var_dump( is_valid_version( '0.0.0' ) ); // false
var_dump( is_valid_version( '0.0.1' ) ); // true
var_dump( is_valid_version( '0.1.0' ) ); // true
var_dump( is_valid_version( '100.53456.fgdf' ) ); //false
var_dump( is_valid_version( array() ) ); //false

Comments

1

Improving on shyammakwana.me's answer, I'd suggest using:

\d{1,2}\.\d{1,2}\.\d{1,2}

Because the + plus quantifier is greedy by default and would match:

9999323.32532553.893588972350897327

As well as:

1.1.1

Using curly braces gives allows you to be more specific and determine if the specified version isn't formatted properly.

If you wanted to, you could get rid of the second number and just use {1,} to match one or more numbers.

2 Comments

{1,} would match any large number.
@shyammakwana.me I know, I just added that snippet of information at the end to let the OP know that it was possible to use curly braces like that.
1

If you just explode the dot (.) then each item is limited to a maximum length of 2.

$version = "25.22.01";
$bool = true;
foreach(explode(".", $version) as $part) {
  if(strlen($part) > 2) {
    $bool = false;
  }
}

// Expected result: "true"
var_dump($bool);

Here is a working example at 3v4l.org.

5 Comments

This succeeds for $version = "f.g.h";
Quite frankly, That doesn't bother me much. If $version can become "f.g.h" then there is something wrong with the code setting $version.
Based on the question it sounds like OP is looking to use this code to properly set $version because the data is coming from an unlabeled source.
If that is the case then I find this a xy problem. Or a wrongly formulated question.
@Andreas updated my post. Sorry for the incomplete sample.

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.