2
\$\begingroup\$

Only these formats are accepted.

  1. 1.1.1
  2. 1.1.1-r
  3. 1.1.1-b
  4. 1.1.1-r1
  5. 1.1.1-b1

I wrote this code. What don't I like in it? I used parentheses and now I have two groups. In fact, I don't need to do anything with groups. And there might be some bugs as well.

package com.sandbox;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
/**
 * @param args
 */
public static void main(String[] args) {
    checkVersion("10.22.5-r");
}

private static void checkVersion(String current) {
    String regex = "([1-9]\\d*)\\.(\\d+)\\.(\\d+)-[b|r](?:[1-9]\\d*)*";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcherCurrent = pattern.matcher(current);
    System.out.println("Matches: " + matcherCurrent.matches());
    System.out.println("The first digit: " + matcherCurrent.group(1));
    System.out.println("The second digit: " + matcherCurrent.group(2));
    System.out.println("The third digit: " + matcherCurrent.group(3));

    // Compare and decide whether an update is necessary
}

}

Thank you for the answers you give me. I'll vote up as soon as I have enough reputation.

\$\endgroup\$
  • \$\begingroup\$ Your last quantifier, {0,1} is the same as ?. \$\endgroup\$ – p.s.w.g Apr 6 '13 at 7:05
  • \$\begingroup\$ @p.s.w.g, yes, I meant "once or not at all." \$\endgroup\$ – Maksim Dmitriev Apr 8 '13 at 10:29
3
\$\begingroup\$

It seems to me that you're using * when it looks like that's not the behaviour you want.

i.e. this bit -(b|r)* do you really mean a dash followed by either a 'b' or an 'r' zero or more times? I think it's more likely that you meant more along the lines of: there can be a dash followed by a 'b' or an 'r' but there doesn't have to be.

Do you want 1.1.1-brrrrrrrrrrr1 to match? What's the goal of the regex, is it just to see if it fits the pattern or do you want to use it to get the various numbers out?

Btw: If you don't care about groups you can use (?: ) instead of () to create non capturing groups.

Edit:

I think your regex needs to be more like: ^([1-9]\\d*)\\.(\\d+)\\.(\\d+)(?:-[br]{1}[0-9]?\\d*)?$ This makes everything following the first 3 numbers optional.

I do wonder whether a regex is the right option though... If you know the strings you are comparing are definitely well formed version numbers just do normal string manipulation.

// Pseudocode
String versionNumber = "1.1.1-r1";
int indexOfDash = versionNumber.indexOf("-");
if (indexOfDash != -1) 
{
    versionNumber = versionNumber.substring(0, indexOfDash);
}
String[] numbers = versionNumber.split(".");

// Now compare your numbers.

I generally like to avoid regular expressions as they are a lot more difficult to get right than people give them credit for. However, if you also need to check that it is a well formed version number you probably want to use the regex option.

In fact, I got the regex wrong - edited now. I changed the matching for the final part of the version number and added in the anchors.

\$\endgroup\$
  • \$\begingroup\$ I edited the question. The goal of the regex is to extract three digits from two string representations of a version: from a current one and from a new one. After that I'll return a boolean result (whether we need to update the current version). Now, I don't take into account r (release) and b (beta) symbols and any digits after them. \$\endgroup\$ – Maksim Dmitriev Apr 8 '13 at 10:33
  • \$\begingroup\$ @RedPlanet - I've responded based on your update. \$\endgroup\$ – RobH Apr 8 '13 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.