2

I'm trying to retrieve only the version number out of a string, but the strings aren't formatted in a specific. For example, the strings may be written in (but not limited to) any of the following formats

  • "Angry Birds v2.0.0"
  • "Angry Birds 2.0.0"
  • "v1.25"
  • "Version: 1.3"
  • " 2.0.1 "

I need to create a php function that will return ONLY the version number (ex: "2.0.0" from each of these strings. Would using regular expressions be useful at all in this task? If so, what built in PCRE (perl compatible regular expressions) PHP functions should I make use of?

Please keep in mind I have very little understanding of regular expressions. Thanks!

2 Answers 2

3

Try this:

function GetVersion($string)
{
    if (preg_match("#(\d+\.\d+(\.\d+)*)#", $string, $match)) {
        return $match[1];
    }
}

$test_strings = array(
    "Angry Birds v2.0.0",
    "Angry Birds 2.0.0",
    "v1.25",
    "Version: 1.3",
    " 2.0.1 ",
    "Dots4You v3.15"
);

foreach ($test_strings as $string) {
    printf("%s<br>", GetVersion($string));
}

RESULT:

2.0.0

2.0.0

1.25

1.3

2.0.1

3.15

@Tim Pietzcker:

Your code will fail when project's name alone will contain a digit, for example "Dots4You v3.15" will catch "4" as a version. Version should contain at least 2 digits and 1 dot.

Sign up to request clarification or add additional context in comments.

1 Comment

Your version is a) inelegant (DRY!) and b) also has a bug: Try UltraEdit 17.30.0.1002 (actual version number).
2

This sounds like a job that regexes are well suited for.

For example:

if (preg_match('/\d+(?:\.\d+)*/', $subject, $regs)) {
    $result = $regs[0];
} else {
    $result = "";
}

Explanation:

\d+  # Match one or more digits
(?:  # Try to match...
 \.  # a dot
 \d+ # and one or more digits...
)*   # zero or more times.

This also matches single version numbers like "Acrobat Reader 9"; if you don't want that and require at least one dot, simply use a + instead of a *: /\d+(?:\.\d+)+/

Or, you could use a word boundary anchor to make sure the regex never matches within a word like "Dots4You": /\d+(?:\.\d+)*\b/

4 Comments

thank you! Could you explain what '/\d+(?:\.\d+)*/' means? I look at it and I just see gibberish, lol.
No problem. Check out regular-expressions.info for a great regex tutorial.
@Czarek: Um, where? Ah, I've seen the comment in your answer. So what about version numbers without a dot in them?
We could set priority, first try to match version with a dot, then if there are still 2 possible versions with only 1 digit - take the last.

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.