Click here to Skip to main content
15,878,959 members
Articles / General Programming / String
Tip/Trick

Regex to Match Version Number Beginning with a Specific Digit

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
20 Aug 2022CPOL4 min read 9.4K   2  
Example of how to use the caret (^) in Regexes that have specific matching requirements
This article explores the method to re-program a script to correctly identify the version numbers that need updating.

Introduction

The requirement in my job was encountered recently, wherein access was given to a folder full of configuration files.

The task is to fix a script that replaced the file version numbers.

The issue was that the script was not making the correct replacement, thereby fouling up the operation of a system that depended on the configuration files.

The middles of some version numbers that contained, but did not begin with, a specific digit, were being replaced when this was not the intended functionality.

We explore in this article the way to re-program the script in order to correctly identify the version numbers that need updating.

Background

The NuGet package called PostSharp is highly useful. However, its authors frequently update it. There is a requirement in our organization, that all software depending on the PostSharp NuGet packages must always use the very latest version.

Currently, the PostSharp version number is 6.10.15 as of the time of writing this article. I have a number of packages.config files that need to have the version number updated in them, so then I can do a nuget restore on the command line to update the packages.

Therefore, I conceived the notion to write a C# script in LINQPad that would iterate through the packages.config files and *.csproj files in a root directory, replacing the version numbers in the files with the latest version that was scraped from the NuGet website.

Regular-Expression ("Regex" For Short) Hell

The Task at Hand

I am trying to match a version number (to replace it in various config files).

The version number I want to match:

  • Always consists of three numbers, 0-99 inclusive, separated by dots
  • The first number is always a 6

For example, 6.10.14 is an example version number.

Current Code

To do the replacement, I utilized the code:

C#
public static class Update
{
    private static string PostSharpVersionToLatest(string contents)
    {
        var result = string.Empty;

        if (string.IsNullOrWhiteSpace(contents)) return result;

        try
        {
            result =
                Regex.Replace(
                    contents,
                    @"6\.\d+\.\d+",
                    LATEST_POSTSHARP_VERSION
                );
            result =
                Regex.Replace(
                    result,
                    @"6\.\d+\.\d+\-rc",
                    LATEST_POSTSHARP_VERSION
                );
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);

            result = string.Empty;
        }

        return result;
    }
}

The Regex being used to find and replace version numbers is 6\.\d+\.\d+.

It seemed like the correct Regex at the time.

However, elsewhere in the text files I am searching and doing replacements in, there are other version numbers, say, 16.301.204959.29, or somesuch. The pattern I am utilizing matches these also, and that's not what I want. I want only the 6. in the beginning to match, not the version numbers that have, say, 16. in the beginning, to also match.

The problem that keeps happening is that the 6.301.204959 text in the longer version number is also matched and replaced, which leads to packages.config files getting corrupted.

Regex Hero to the Rescue

There is a really handy utility out there -- which I recommend you get -- called Regex Hero.

I am going to utilize it to find out what's wrong with my regex. The Regex Hero window, shown matching the target string 6.10.14 with the regex 6\.\d+\.\d+, is visible in Figure 1.

Image 1

Figure 1. The Regex Hero window is shown with the target string 6.10.14 being matched by the regex 6\.\d+\.\d+.

It appears that our pattern works perfectly. However, let's suppose the longer version number, 16.301.204959.29, is also in our text files that we're doing our find and replace operation in.

We put it into Regex Hero, in the Target String box, using the same value for the Regular Expression field, and get the results as shown in Figure 2:

Image 2

Figure 2. Regex Hero displays a partial match to the target string 16.301.204959.29.

One can imagine that this may lead to problems if we try to do a textual Replace operation and we only wish to target those version numbers that explicitly begin with a 6 and not a 16, say, or 36, etc.

Eat Your Carets [sic]

I know I can utilize a caret (^) at the beginning of my regex. According to this blog post:

Quote:

You can use the caret symbol (^) at the start of a regular expression to indicate that a match must occur at the beginning of the searched text.

My thought process was to try the following regex: ^6\.\d+\.\d+. As can be seen in Regex Hero, there are no matches to the version number 16.301.204959.29, as is shown in Figure 3:

Image 3

Figure 3. Regex Hero displays no matches for the version number 16.301.204959.29 with the regex ^6\.\d+\.\d+.

Let me just try the sample version number 6.10.14 with my new regex, as shown in Figure 4:

Image 4

Figure 4. Regex Hero displays a positive match on the value 6.10.14 with the regex ^6\.\d+\.\d+.

Conclusions

We can see that the issue of creating a regex to match only those values that start with a specific digit can be created by using a caret, ^, at the beginning of the regex.

History

  • 20th August, 2022: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
United States United States
Brian C. Hart, Ph.D., is a strategic engagement leader on a mission to leverage space technology to protect U.S. interests and assets against adversaries. Throughout Dr. Hart's career, he has enjoyed: Working closely with business executives to provide strategic direction and leadership, translating customer and competitive intelligence into compelling capture strategies and solutions, and mentoring teams to enhance individual and company capabilities while fostering an engaging and accountable environment, being involved in STEAM initiatives and education to develop greater awareness in the community, and serving the armed forces with the U.S. Navy and U.S. Army National Guard. He is excited to begin developing his career in Jacobs's Critical Mission Systems business unit, supporting NORAD and the U.S. Space Force.

Comments and Discussions

 
-- There are no messages in this forum --