regex 在C#中提取字符串末尾的数字

mklgxw1f  于 2023-04-13  发布在  C#
关注(0)|答案(9)|浏览(168)

可能分析得有点过了,但是stackoverflow建议如何返回一个包含在字符串末尾的整数。
到目前为止,我已经考虑使用一个简单的循环,LINQ和正则表达式,但我很好奇我会从社区得到什么方法。显然,这不是一个很难解决的问题,但可能有很多的解决方案。
更具体地说,如何创建一个函数来返回一个任意长的整数/long,并将其附加在任意长字符串的末尾?

CPR123 => 123
ABCDEF123456 => 123456
kb5ga3dv

kb5ga3dv1#

使用此正则表达式:

\d+$

// RegexOptions.RightToLeft – is optional, but will increase performance
var result = Regex.Match(input, @"\d+$", RegexOptions.RightToLeft).Value;

或者没有正则表达式的一行程序:

var result = input[^input.Reverse().TakeWhile(char.IsDigit).Count()..];

更有效的方法:

int numberOfDigitsAtEnd = 0;
for (var i = input.Length - 1; i >= 0; i--)
{
    if (!char.IsNumber(input[i]))
    {
        break;
    }

    numberOfDigitsAtEnd++;
}
        
var result = input[^numberOfDigitsAtEnd..];
ldxq2e6h

ldxq2e6h2#

强制性LINQ单线性

var input = "ABCD1234";
var result = string.Concat(input.ToArray().Reverse().TakeWhile(char.IsNumber).Reverse());
jmo0nnb3

jmo0nnb33#

\d+$这样的正则表达式模式有点昂贵,因为默认情况下,字符串是从左到右解析的。一旦正则表达式引擎在12abc34中找到1,它就会继续匹配2,当遇到a时,匹配失败,尝试下一个位置,依此类推。
然而,在.NET正则表达式中,有一个RegexOptions.RightToLeft修饰符,它使正则表达式引擎从右到左解析字符串,这样你就可以更快地找到接近末尾的匹配项。

var result = Regex.Match("000AB22CD1234", @"\d+$", RegexOptions.RightToLeft);
if (result.Success) 
{ 
    Console.Write(result.Value);
}  // => 1234

参见online C# demo

e1xvtsh3

e1xvtsh34#

根据我的经验,Regex是最简单的。

Regex ex = new Regex(@"(\d+)$")

这个应该和它匹配。把它 Package 在一个函数里。

yjghlzjz

yjghlzjz5#

[^0-9]+([0-9]+)

我想应该做

u91tlkcl

u91tlkcl6#

是否始终采用字母数字格式?
在这种情况下,这将起作用:

Regex _cellAddressRegex = new Regex(@"(?<Column>[a-z]+)(?<Row>[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var rowm = Convert.ToInt32(parts.Groups["Row"]);
q3aa0525

q3aa05257#

我可以疯了吗?

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());
}
sqxo8psd

sqxo8psd8#

一个简单的循环可能会在其简单性和效率方面击败任何其他解决方案。并且最终返回的字符串可以只复制一次,而无需使用Stack,StringBuilder,string.Concat或其他更复杂的字符串支持函数。

string GetNumberFromEnd(string text)
{
    int i = text.Length - 1;
    while (i >= 0)
    {
        if (!char.IsNumber(text[i])) break;
        i--;
    }
    return text.Substring(i + 1);
}

或者它甚至可以直接作为int类型返回:

bool GetIntFromEnd(string text, out int number)
{
    int i = text.Length - 1;
    while (i >= 0)
    {
        if (!char.IsNumber(text[i])) break;
        i--;
    }
    return int.TryParse(text.Substring(i + 1), out number);
}
js4nwp54

js4nwp549#

如果不使用RegEx(可能很难理解)或Linq和数组操作(可能很慢),则可以使用扩展方法中的简单循环。
它可用于longintulonguint或其他,同时调整+-检查。
它也可以用于解析floatdoubledecimal
这个方法也可以写为Parse以包含异常。

执行情况

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(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");
};

输出

"" 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

相关问题