0

I need some help with regular expression.

I need to search for "Android 2.2.x" where x can be 1-9 in a string so I created this RegEx Androind 2.2.\d{1} This works fine.

Now I want to find Android 2.2 in the in the string

If I search using Regex "Androind 2.2" it matches both "Android 2.2" and "Android 2.2.x" But I want regex to match only "Android 2.2"

Can anyone please help me with this.

Thanks,

1
  • FWIW: You don't need to do \d{1} if you just need one digit, \d will do. Commented Feb 23, 2012 at 21:51

3 Answers 3

2

Use negative lookahead. "Android 2.2(?!\.\d)" matches "Android 2.2" but not "Android 2.2.1", "Android 2.2.2", "Android 2.2.10", etc. It will also match "Android 2.2." if the next character is not a digit or the end of the string is reached.

See Grouping Constructs for more information.

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

4 Comments

Thanks for your help. "Android 2.2(?!\.\d)" works for all the scenarios.
This will match "Android 2.2" in "Android 2.22". Use the lookahead (?!\.?\d) to prevent that.
Note that "Android 2.2(?!\.\d)" also matches "Android 2.20", so if you need to future-proof yourself for 18 versions from now you might try "Android 2.2(?!\.?\d)" (make the period in the assertion optional).
You guys are amazing. I need to spend more time learning RegEx.
0

If this string Android 2.2 is followed by end of string, you can include $ after the pattern which matches the end of string.

Otherwise, you can do something like Android 2.2[^0-9.] to make sure that this string is not followed by dot or digits.

One argument against the second case is that you could have a string like "You are using Andoid 2.2." Where the last . is there to just end a sentence... Would you like to match that string as well?

2 Comments

Thanks for your reply. $ option will not work because there would be more text around the "Android 2.2" Android 2.2 can be anywhere in the string.
As far second option Android "2.2[^0-9.]" it doesn't find a match for "test Android 2.2"
0

Just to toss out another approach, if you need to provide different behavior for different versions you could do this:

string pattern = @"Android (?<major>\d+)\.(?<minor>\d+)(\.(?<revision>\d+))?";
Match match = Regex.Match(text, pattern);

if (match.Success)
{
    int major = int.Parse(match.Groups["major"].Value);
    int minor = int.Parse(match.Groups["minor"].Value);
    int revision;

    if (!int.TryParse(match.Groups["revision"].Value, out revision))
        revision = 0;

    if (major == 2 && minor == 2)
    {
        if (revision == 0)
        {
            // Process version 2.2
        }
        else
        {
            // Process version 2.2.x, where x > 0
        }
    }
}

That will match a major version followed by a minor version optionally followed by a revision, and give you access to each of those three numbers. Note that if no revision is specified it's treated the same as if it were 0 (i.e. "Android 2.2" == "Android 2.2.0").

You can also use the Version class to do some of the work, like this:

string pattern = @"Android (?<version>\d+\.\d+(\.\d+)?)";
Match match = Regex.Match(text, pattern);

if (match.Success)
{
    Version version = Version.Parse(match.Groups["version"].Value);

    if (version.Major == 2 && version.Minor == 2)
    {
        if (version.Build < 1)
        {
            // Process version 2.2
        }
        else
        {
            // Process version 2.2.x, where x > 0
        }
    }
}

There the third number component is called "Build", not "Revision". Note that the Build property returns 0 if the value is 0 and -1 if the value is not specified.

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.