How to get the last char in string

Viewed 137

So i have a textfile with a lot of packages "Data.Interface.4.87.2" "GuiTools.4.92.401-alpha01400" "Drivers.4.87.400-alpha01000" And i only want the numbers: So 4.87.2, 4.92.401, 4.87.400

But the problem is the GetBetween method removes the last char

Expected output : 4.92.401

Actual output : 4.92.4

Another example:

Expected output : 4.87.2

Actual output : 4.87.

Expected output : 4.87.400

Actual output : 4.87.4

Method to get everything between "package " to end of string

private string GetBetween(string strSource, string strStart, string strEnd)
        {
            if (strSource.Contains(strStart) && strSource.Contains(strEnd))
            {
                int Start, End;
                Start = strSource.IndexOf(strStart, 0) + strStart.Length;
                End = strSource.IndexOf(strEnd, Start);
                return strSource.Substring(Start, End - Start);
            }

            return "";
        }
private string GetPackageVersion(string line)
        {
          string packageinfo = GetBetween(line, "package ", line[line.Length-1].ToString());
          string VersionNumber = "";
                for (int i = 0; i < packageinfo.Length; i++)
                {
                    if (char.IsDigit(packageinfo[i]) || packageinfo[i] == '.')
                    {
                        VersionNumber += packageinfo[i];
                    }
                }
            VersionNumber = ReverseString(VersionNumber);
            VersionNumber = RemoveDotsFromEndofString(VersionNumber);
            return ReverString(VersionNumber);
         }
 private string RemoveDotsFromEndofString(string line)
        {
            if (line.Contains("alpha"))
            {
                int pos = line.IndexOf("alpha");
                if (pos >= 0)
                {
                    line = line.Remove(pos);
                }

                for (int i = line.Length; i >= 0; i--)
                {
                    if (line[i - 1] != '.')
                    {
                        return line;
                    }

                    line = line.Remove(i - 1, 1);
                }
            }
            for (int i = line.Length; i >= 0; i--)
            {
                if (line[i - 1] != '.')
                {
                    return line;
                }

                line = line.Remove(i - 1, 1);
            }

            return "";
        }
        private string ReverseString(string s)
        {
            char[] charArray = s.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }
1 Answers

The problem is in the GetBetween second argument:

string packageinfo = GetBetween(line, "package ", line[line.Length-1].ToString());
      

please, note, that for, say "GuiTools.4.92.401-alpha01400"

line[line.Length-1].ToString() == "0"

That's why you trim the first 0 and all characters after it:

"Check the package GuiTools.4.92.401-alpha01400"
                   ^              ^
               from "package" up to "0": GuiTools.4.92.4 

Let's use regular expression: to Match the substring:

using System.Text.RegularExpressions;

...

private static string GetPackageVersion(string line) => Regex
  .Match(line, 
       @"\b\p{L}+\.(?<value>[0-9]+(\.[0-9]+)+)", 
         RegexOptions.RightToLeft)
  .Groups["value"]
  .Value;

Pattern explained:

We use \b\p{L}+\.(?<value>[0-9]+(\.[0-9]+)+) pattern to match, its components are

 prefix (like `GuiTools`)
   \b        - word boundary, we don't want 1223x be name of a package
   p{L}+     - one or more letters
   \.        - dot '.'
 group with "value" name where we have the version number
   (?<value> - group start, its title
    [0-9]+   - one or more digit 0..9
 (\.[0-9]+)+ - one or more chunks starting with . and has one or more digits
   )         - group end          

Demo:

  string[] tests = new string[] {
    "Data.Interface.4.87.2",
    "GuiTools.4.92.401-alpha01400", 
    "Drivers.4.87.400-alpha01000", 
    "Please, have a look at routine.1.0.0.7",
    "Validate MyModule.1.0.0.7-beta1234",
    "Inspect MyAssembly.1.2.3.4.5.6-alpha123 and let me know"
  };

  var report = string.Join(Environment.NewLine, tests
    .Select(test => $"{test,-60} => {GetPackageVersion(test)}"));

  Console.Write(report);

Output:

Data.Interface.4.87.2                                        => 4.87.2
GuiTools.4.92.401-alpha01400                                 => 4.92.401
Drivers.4.87.400-alpha01000                                  => 4.87.400
Please, have a look at routine.1.0.0.7                       => 1.0.0.7
Validate MyModule.1.0.0.7-beta1234                           => 1.0.0.7
Inspect MyAssembly.1.2.3.4.5.6-alpha123 and let me know      => 1.2.3.4.5.6

Please, fiddle yourself

Related