Probably over analysing this a little bit but how would stackoverflow suggest is the best way to return an integer that is contained at the end of a string.
Thus far
Regex pattern like \d+$
is a bit expensive since, by default, a string is parsed from left to right. Once the regex engine finds 1
in 12abc34
, it goes on to match 2
, and when it encounters a
, the match is failed, next position is tried, and so on.
However, in .NET regex, there is a RegexOptions.RightToLeft
modifier. It makes the regex engine parse the string from right to left and you may get matches that are known to be closer to the end much quicker.
var result = Regex.Match("000AB22CD1234", @"\d+$", RegexOptions.RightToLeft);
if (result.Success)
{
Console.Write(result.Value);
} // => 1234
See the online C# demo.
Am I allowed to go crazy with this?
using System.Text;
using System.Linq;
static string GetNum(string input)
{
StringBuilder sb = new StringBuilder();
for (int i = input.Length - 1; i >= 0; i--)
{
if (input[i] < 48 || input[i] > 57)
break;
sb.Append(input[i]);
}
return String.Concat(sb.ToString().ToCharArray().Reverse());
}
Use this regular expression:
\d+$
var result = Regex.Match(input, @"\d+$").Value;
or using Stack
, probably more efficient:
var stack = new Stack<char>();
for (var i = input.Length - 1; i >= 0; i--)
{
if (!char.IsNumber(input[i]))
{
break;
}
stack.Push(input[i]);
}
var result = new string(stack.ToArray());
[^0-9]+([0-9]+)
should do it I think
Regex would be the easiest, as far as my experience.
Regex ex = new Regex(@"(\d+)$")
This should match it. Just wrap that in a function.
Without using RegEx that can be hard to understand, or Linq and array manipulation that can be slow, a simple loop in an extension method can be used.
It can be used for long
or int
or ulong
or uint
or other while adapting the +
and -
check.
It can be adapted to parse float
and double
or decimal
too.
This method can also be written as a Parse
to have exceptions.
Implementation
static public class StringHelper
{
static public bool TryParseEndAsLong(this string str, out long result)
{
result = 0;
if ( string.IsNullOrEmpty(str) )
return false;
int index = str.Length - 1;
for ( ; index >= 0; index-- )
{
char c = str[index];
bool stop = c == '+' || c == '-';
if ( !stop && !char.IsDigit(c) )
{
index++;
break;
}
if ( stop )
break;
}
return index <= 0 ? long.TryParse(str, out result)
: long.TryParse(str.Substring(index), out result);
}
}
Test
test(null);
test("");
test("Test");
test("100");
test("-100");
test("100-200");
test("100 - 200");
test("Test 100");
test("Test100");
test("Test+100");
test("Test-100");
test("11111111111111111111");
Action<string> test = str =>
{
if ( str.TryParseEndAsLong(out var value) )
Console.WriteLine($"\"{str}\" => {value}");
else
Console.WriteLine($"\"{str}\" has not a long at the end");
};
Output
"" has not a long at the end
"" has not a long at the end
"Test" has not a long at the end
"100" => 100
"-100" => -100
"100-200" => -200
"100 - 200" => 200
"Test 100" => 100
"Test100" => 100
"Test+100" => 100
"Test-100" => -100
"11111111111111111111" has not a long at the end