Home > Mobile >  Find the last occurrence of a number in a string, and split the string by that value
Find the last occurrence of a number in a string, and split the string by that value

Time:10-14

What I am trying to accomplish is finding the last number in a string and split by that value.

string packageSize = "4/8.75LB";

Above I have a string that I would like to split into a string array, and put those into two different columns in the database. The first part would be a decimal, and the last part would be a string or varchar.

I have this code below and it seems to be working. Just wondering if there is a better solution, or an answered question that I missed.

string value = Regex.Match(packageSize, @"(\d )(?!.*\d)", RegexOptions.RightToLeft).ToString();
int lastIndex = packageSize.LastIndexOf(value)   value.Length;
string packageLoad = packageSize.Substring(0, lastIndex);
decimal loadDecimal = Convert.ToDecimal(packageLoad);

Thanks for any help!

CodePudding user response:

You could use 2 capture groups for the first part before and the second part after matching the last digit.

If you want to match at least a single char per group, change the quantifier to instead of *

^(.*)[0-9](\D*)$
  • ^ Start of string
  • (.*) Capture group 1, match any char
  • [0-9] Match a single digits 0-9
  • (\D*) Capture group 2, optionally match non digits
  • $ End of string

Regex demo

For example

string packageSize = "4/8.75LB";
Regex r = new Regex(@"^(.*?)[0-9](\D*)$");
foreach (Match m in r.Matches(packageSize))
{
    Console.WriteLine(m.Groups[1].Value);
    Console.WriteLine(m.Groups[2].Value);
}

Output

4/8.7
LB

CodePudding user response:

You can use

var output = Regex.Split(packageSize, @"(\d)(?=\D*$)");

The (\d)(?=\D*$) regex matches and captures a digit with (\d) that is also returned with Regex.Split (it outputs captured substrings). The (?=\D*$) makes sure the (\d) matches the last digit in the string.

See the C# demo:

var packageSize = "4/8.75LB";
var result = Regex.Split(packageSize, @"(\d)(?=\D*$)");
foreach (var s in result)
    Console.WriteLine(s);

// => 4/8.7
//    5
//    LB

CodePudding user response:

"I want to find the last digit, and split the string into two either side of it"

Performance-wise I don't think you'll do much better than a loop:

for(int i = str.Length-1; i>=0; i--)
  if(Char.IsDigit(str[i])){
    return (str[..i], str[(i 1)..]);
  }

It returns a tuple of ("4/8.7", "LB")

--

You could jiggle that to one of:

var i = str.LastIndexOfAny("0123456789".ToCharArray());

var i = Array.FindLastIndex(str.ToCharArray(), Char.IsDigit);

return (str[..i], str[(i 1)..]);

What puzzles me is that the spec you're giving in the comments is nothing like the code you're giving in the question.. Your code "works" but there's no way that 4/8.7 would Convert.ToDecimal..

CodePudding user response:

Not 100% sure if I understood the requirements correctly, but this Regex will capture the last number in the input string, decimal or not, in the first group and the following characters in the second group:

(\d (?:\.\d )?)(\D*)$

So, the input string "4/8.75LB" would be split into:

  • Group 1: "8.75"
  • Group 2: "LB"
  • Related